media/mtransport/transportlayerloopback.h

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:eef7f2ceddc7
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 // Original author: ekr@rtfm.com
8
9 #ifndef transportlayerloopback_h__
10 #define transportlayerloopback_h__
11
12 #include "nspr.h"
13 #include "prio.h"
14 #include "prlock.h"
15
16 #include <memory>
17 #include <queue>
18
19
20 #include "nsAutoPtr.h"
21 #include "nsCOMPtr.h"
22 #include "nsITimer.h"
23
24
25 #include "m_cpp_utils.h"
26 #include "transportflow.h"
27 #include "transportlayer.h"
28
29 // A simple loopback transport layer that is used for testing.
30 namespace mozilla {
31
32 class TransportLayerLoopback : public TransportLayer {
33 public:
34 TransportLayerLoopback() :
35 peer_(nullptr),
36 timer_(nullptr),
37 packets_(),
38 packets_lock_(nullptr),
39 deliverer_(nullptr) {}
40
41 ~TransportLayerLoopback() {
42 while (!packets_.empty()) {
43 QueuedPacket *packet = packets_.front();
44 packets_.pop();
45 delete packet;
46 }
47 if (packets_lock_) {
48 PR_DestroyLock(packets_lock_);
49 }
50 timer_->Cancel();
51 deliverer_->Detach();
52 }
53
54 // Init
55 nsresult Init();
56
57 // Connect to the other side
58 void Connect(TransportLayerLoopback* peer);
59
60 // Disconnect
61 void Disconnect() {
62 TransportLayerLoopback *peer = peer_;
63
64 peer_ = nullptr;
65 if (peer) {
66 peer->Disconnect();
67 }
68 }
69
70 // Overrides for TransportLayer
71 virtual TransportResult SendPacket(const unsigned char *data, size_t len);
72
73 // Deliver queued packets
74 void DeliverPackets();
75
76 TRANSPORT_LAYER_ID("loopback")
77
78 private:
79 DISALLOW_COPY_ASSIGN(TransportLayerLoopback);
80
81 // A queued packet
82 class QueuedPacket {
83 public:
84 QueuedPacket() : data_(nullptr), len_(0) {}
85 ~QueuedPacket() {
86 delete [] data_;
87 }
88
89 void Assign(const unsigned char *data, size_t len) {
90 data_ = new unsigned char[len];
91 memcpy(static_cast<void *>(data_),
92 static_cast<const void *>(data), len);
93 len_ = len;
94 }
95
96 const unsigned char *data() const { return data_; }
97 size_t len() const { return len_; }
98
99 private:
100 DISALLOW_COPY_ASSIGN(QueuedPacket);
101
102 unsigned char *data_;
103 size_t len_;
104 };
105
106 // A timer to deliver packets if some are available
107 // Fires every 100 ms
108 class Deliverer : public nsITimerCallback {
109 public:
110 Deliverer(TransportLayerLoopback *layer) :
111 layer_(layer) {}
112 virtual ~Deliverer() {
113 }
114 void Detach() {
115 layer_ = nullptr;
116 }
117
118 NS_DECL_THREADSAFE_ISUPPORTS
119 NS_DECL_NSITIMERCALLBACK
120
121 private:
122 DISALLOW_COPY_ASSIGN(Deliverer);
123
124 TransportLayerLoopback *layer_;
125 };
126
127 // Queue a packet for delivery
128 nsresult QueuePacket(const unsigned char *data, size_t len);
129
130 TransportLayerLoopback* peer_;
131 nsCOMPtr<nsITimer> timer_;
132 std::queue<QueuedPacket *> packets_;
133 PRLock *packets_lock_;
134 nsRefPtr<Deliverer> deliverer_;
135 };
136
137 } // close namespace
138 #endif

mercurial