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 transportlayer_h__ 10 #define transportlayer_h__ 11 12 #include "sigslot.h" 13 14 #include "mozilla/DebugOnly.h" 15 #include "mozilla/RefPtr.h" 16 #include "nsCOMPtr.h" 17 #include "nsIEventTarget.h" 18 19 #include "m_cpp_utils.h" 20 21 namespace mozilla { 22 23 class TransportFlow; 24 25 typedef int TransportResult; 26 27 enum { TE_WOULDBLOCK = -1, TE_ERROR = -2, TE_INTERNAL = -3 }; 28 29 #define TRANSPORT_LAYER_ID(name) \ 30 const std::string id() const override { return name; } \ 31 static std::string ID() { return name; } 32 33 // Abstract base class for network transport layers. 34 class TransportLayer : public sigslot::has_slots<> { 35 public: 36 // The state of the transport flow 37 // We can't use "ERROR" because Windows has a macro named "ERROR" 38 enum State { TS_NONE, TS_INIT, TS_CONNECTING, TS_OPEN, TS_CLOSED, TS_ERROR }; 39 40 // Is this a stream or datagram flow TransportLayer()41 TransportLayer() : state_(TS_NONE), flow_id_(), downward_(nullptr) {} 42 ~TransportLayer()43 virtual ~TransportLayer() {} 44 45 // Called to initialize 46 nsresult Init(); // Called by Insert() to set up -- do not override InitInternal()47 virtual nsresult InitInternal() { return NS_OK; } // Called by Init 48 49 // Called when inserted into a flow 50 virtual void Inserted(TransportFlow *flow, TransportLayer *downward); 51 52 // Downward interface downward()53 TransportLayer *downward() { return downward_; } 54 55 // Get the state state()56 State state() const { return state_; } 57 // Must be implemented by derived classes 58 virtual TransportResult SendPacket(const unsigned char *data, size_t len) = 0; 59 60 // Get the thread. GetThread()61 const nsCOMPtr<nsIEventTarget> GetThread() const { return target_; } 62 63 // Event definitions that one can register for 64 // State has changed 65 sigslot::signal2<TransportLayer *, State> SignalStateChange; 66 // Data received on the flow 67 sigslot::signal3<TransportLayer *, const unsigned char *, size_t> 68 SignalPacketReceived; 69 70 // Return the layer id for this layer 71 virtual const std::string id() const = 0; 72 73 // The id of the flow flow_id()74 const std::string &flow_id() const { return flow_id_; } 75 76 protected: WasInserted()77 virtual void WasInserted() {} 78 virtual void SetState(State state, const char *file, unsigned line); 79 // Check if we are on the right thread CheckThread()80 void CheckThread() const { MOZ_ASSERT(CheckThreadInt(), "Wrong thread"); } 81 82 State state_; 83 std::string flow_id_; 84 TransportLayer *downward_; // The next layer in the stack 85 nsCOMPtr<nsIEventTarget> target_; 86 87 private: 88 DISALLOW_COPY_ASSIGN(TransportLayer); 89 CheckThreadInt()90 bool CheckThreadInt() const { 91 bool on; 92 93 if (!target_) // OK if no thread set. 94 return true; 95 96 NS_ENSURE_SUCCESS(target_->IsOnCurrentThread(&on), false); 97 NS_ENSURE_TRUE(on, false); 98 99 return true; 100 } 101 }; 102 103 #define LAYER_INFO \ 104 "Flow[" << flow_id() << "(none)" \ 105 << "]; Layer[" << id() << "]: " 106 #define TL_SET_STATE(x) SetState((x), __FILE__, __LINE__) 107 108 } // namespace mozilla 109 #endif 110