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 #include "nsCOMPtr.h" 20 #include "nsINamed.h" 21 #include "nsITimer.h" 22 23 #include "m_cpp_utils.h" 24 #include "transportflow.h" 25 #include "transportlayer.h" 26 27 // A simple loopback transport layer that is used for testing. 28 namespace mozilla { 29 30 class TransportLayerLoopback : public TransportLayer { 31 public: TransportLayerLoopback()32 TransportLayerLoopback() 33 : peer_(nullptr), 34 timer_(nullptr), 35 packets_(), 36 packets_lock_(nullptr), 37 deliverer_(nullptr), 38 combinePackets_(false) {} 39 ~TransportLayerLoopback()40 ~TransportLayerLoopback() { 41 while (!packets_.empty()) { 42 MediaPacket* packet = packets_.front(); 43 packets_.pop(); 44 delete packet; 45 } 46 if (packets_lock_) { 47 PR_DestroyLock(packets_lock_); 48 } 49 timer_->Cancel(); 50 deliverer_->Detach(); 51 } 52 53 // Init 54 nsresult Init(); 55 56 // Connect to the other side 57 void Connect(TransportLayerLoopback* peer); 58 59 // Disconnect Disconnect()60 void Disconnect() { 61 TransportLayerLoopback* peer = peer_; 62 63 peer_ = nullptr; 64 if (peer) { 65 peer->Disconnect(); 66 } 67 } 68 CombinePackets(bool combine)69 void CombinePackets(bool combine) { combinePackets_ = combine; } 70 71 // Overrides for TransportLayer 72 TransportResult SendPacket(MediaPacket& packet) override; 73 74 // Deliver queued packets 75 void DeliverPackets(); 76 77 TRANSPORT_LAYER_ID("loopback") 78 79 private: 80 DISALLOW_COPY_ASSIGN(TransportLayerLoopback); 81 82 // A timer to deliver packets if some are available 83 // Fires every 100 ms 84 class Deliverer : public nsITimerCallback, public nsINamed { 85 public: Deliverer(TransportLayerLoopback * layer)86 explicit Deliverer(TransportLayerLoopback* layer) : layer_(layer) {} Detach()87 void Detach() { layer_ = nullptr; } 88 89 NS_DECL_THREADSAFE_ISUPPORTS 90 NS_DECL_NSITIMERCALLBACK 91 NS_DECL_NSINAMED 92 93 private: 94 virtual ~Deliverer() = default; 95 96 DISALLOW_COPY_ASSIGN(Deliverer); 97 98 TransportLayerLoopback* layer_; 99 }; 100 101 // Queue a packet for delivery 102 nsresult QueuePacket(MediaPacket& packet); 103 104 TransportLayerLoopback* peer_; 105 nsCOMPtr<nsITimer> timer_; 106 std::queue<MediaPacket*> packets_; 107 PRLock* packets_lock_; 108 RefPtr<Deliverer> deliverer_; 109 bool combinePackets_; 110 }; 111 112 } // namespace mozilla 113 #endif 114