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