|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: sw=4 ts=4 et : |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #ifndef ipc_glue_MessageLink_h |
|
9 #define ipc_glue_MessageLink_h 1 |
|
10 |
|
11 #include "base/basictypes.h" |
|
12 #include "base/message_loop.h" |
|
13 |
|
14 #include "mozilla/WeakPtr.h" |
|
15 #include "mozilla/ipc/Transport.h" |
|
16 |
|
17 namespace mozilla { |
|
18 namespace ipc { |
|
19 |
|
20 class MessageChannel; |
|
21 |
|
22 struct HasResultCodes |
|
23 { |
|
24 enum Result { |
|
25 MsgProcessed, |
|
26 MsgDropped, |
|
27 MsgNotKnown, |
|
28 MsgNotAllowed, |
|
29 MsgPayloadError, |
|
30 MsgProcessingError, |
|
31 MsgRouteError, |
|
32 MsgValueError |
|
33 }; |
|
34 }; |
|
35 |
|
36 enum Side { |
|
37 ParentSide, |
|
38 ChildSide, |
|
39 UnknownSide |
|
40 }; |
|
41 |
|
42 enum ChannelState { |
|
43 ChannelClosed, |
|
44 ChannelOpening, |
|
45 ChannelConnected, |
|
46 ChannelTimeout, |
|
47 ChannelClosing, |
|
48 ChannelError |
|
49 }; |
|
50 |
|
51 // What happens if Interrupt calls race? |
|
52 enum RacyInterruptPolicy { |
|
53 RIPError, |
|
54 RIPChildWins, |
|
55 RIPParentWins |
|
56 }; |
|
57 |
|
58 class MessageListener |
|
59 : protected HasResultCodes, |
|
60 public mozilla::SupportsWeakPtr<MessageListener> |
|
61 { |
|
62 public: |
|
63 MOZ_DECLARE_REFCOUNTED_TYPENAME(MessageListener) |
|
64 typedef IPC::Message Message; |
|
65 |
|
66 virtual ~MessageListener() { } |
|
67 |
|
68 virtual void OnChannelClose() = 0; |
|
69 virtual void OnChannelError() = 0; |
|
70 virtual Result OnMessageReceived(const Message& aMessage) = 0; |
|
71 virtual Result OnMessageReceived(const Message& aMessage, Message *& aReply) = 0; |
|
72 virtual Result OnCallReceived(const Message& aMessage, Message *& aReply) = 0; |
|
73 virtual void OnProcessingError(Result aError) = 0; |
|
74 virtual void OnChannelConnected(int32_t peer_pid) {} |
|
75 virtual bool OnReplyTimeout() { |
|
76 return false; |
|
77 } |
|
78 |
|
79 virtual void OnEnteredCxxStack() { |
|
80 NS_RUNTIMEABORT("default impl shouldn't be invoked"); |
|
81 } |
|
82 virtual void OnExitedCxxStack() { |
|
83 NS_RUNTIMEABORT("default impl shouldn't be invoked"); |
|
84 } |
|
85 virtual void OnEnteredCall() { |
|
86 NS_RUNTIMEABORT("default impl shouldn't be invoked"); |
|
87 } |
|
88 virtual void OnExitedCall() { |
|
89 NS_RUNTIMEABORT("default impl shouldn't be invoked"); |
|
90 } |
|
91 virtual RacyInterruptPolicy MediateInterruptRace(const Message& parent, |
|
92 const Message& child) |
|
93 { |
|
94 return RIPChildWins; |
|
95 } |
|
96 |
|
97 virtual void ProcessRemoteNativeEventsInInterruptCall() { |
|
98 } |
|
99 |
|
100 // FIXME/bug 792652: this doesn't really belong here, but a |
|
101 // large refactoring is needed to put it where it belongs. |
|
102 virtual int32_t GetProtocolTypeId() = 0; |
|
103 }; |
|
104 |
|
105 class MessageLink |
|
106 { |
|
107 public: |
|
108 typedef IPC::Message Message; |
|
109 |
|
110 MessageLink(MessageChannel *aChan); |
|
111 virtual ~MessageLink(); |
|
112 |
|
113 // n.b.: These methods all require that the channel monitor is |
|
114 // held when they are invoked. |
|
115 virtual void EchoMessage(Message *msg) = 0; |
|
116 virtual void SendMessage(Message *msg) = 0; |
|
117 virtual void SendClose() = 0; |
|
118 |
|
119 virtual bool Unsound_IsClosed() const = 0; |
|
120 virtual uint32_t Unsound_NumQueuedMessages() const = 0; |
|
121 |
|
122 protected: |
|
123 MessageChannel *mChan; |
|
124 }; |
|
125 |
|
126 class ProcessLink |
|
127 : public MessageLink, |
|
128 public Transport::Listener |
|
129 { |
|
130 void OnCloseChannel(); |
|
131 void OnChannelOpened(); |
|
132 void OnTakeConnectedChannel(); |
|
133 void OnEchoMessage(Message* msg); |
|
134 |
|
135 void AssertIOThread() const |
|
136 { |
|
137 NS_ABORT_IF_FALSE(mIOLoop == MessageLoop::current(), |
|
138 "not on I/O thread!"); |
|
139 } |
|
140 |
|
141 public: |
|
142 ProcessLink(MessageChannel *chan); |
|
143 virtual ~ProcessLink(); |
|
144 void Open(Transport* aTransport, MessageLoop *aIOLoop, Side aSide); |
|
145 |
|
146 // Run on the I/O thread, only when using inter-process link. |
|
147 // These methods acquire the monitor and forward to the |
|
148 // similarly named methods in AsyncChannel below |
|
149 // (OnMessageReceivedFromLink(), etc) |
|
150 virtual void OnMessageReceived(const Message& msg) MOZ_OVERRIDE; |
|
151 virtual void OnChannelConnected(int32_t peer_pid) MOZ_OVERRIDE; |
|
152 virtual void OnChannelError() MOZ_OVERRIDE; |
|
153 |
|
154 virtual void EchoMessage(Message *msg) MOZ_OVERRIDE; |
|
155 virtual void SendMessage(Message *msg) MOZ_OVERRIDE; |
|
156 virtual void SendClose() MOZ_OVERRIDE; |
|
157 |
|
158 virtual bool Unsound_IsClosed() const MOZ_OVERRIDE; |
|
159 virtual uint32_t Unsound_NumQueuedMessages() const MOZ_OVERRIDE; |
|
160 |
|
161 protected: |
|
162 Transport* mTransport; |
|
163 MessageLoop* mIOLoop; // thread where IO happens |
|
164 Transport::Listener* mExistingListener; // channel's previous listener |
|
165 }; |
|
166 |
|
167 class ThreadLink : public MessageLink |
|
168 { |
|
169 public: |
|
170 ThreadLink(MessageChannel *aChan, MessageChannel *aTargetChan); |
|
171 virtual ~ThreadLink(); |
|
172 |
|
173 virtual void EchoMessage(Message *msg) MOZ_OVERRIDE; |
|
174 virtual void SendMessage(Message *msg) MOZ_OVERRIDE; |
|
175 virtual void SendClose() MOZ_OVERRIDE; |
|
176 |
|
177 virtual bool Unsound_IsClosed() const MOZ_OVERRIDE; |
|
178 virtual uint32_t Unsound_NumQueuedMessages() const MOZ_OVERRIDE; |
|
179 |
|
180 protected: |
|
181 MessageChannel* mTargetChan; |
|
182 }; |
|
183 |
|
184 } // namespace ipc |
|
185 } // namespace mozilla |
|
186 |
|
187 #endif // ifndef ipc_glue_MessageLink_h |
|
188 |