1 | /* ***** BEGIN LICENSE BLOCK *****
|
---|
2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
---|
3 | *
|
---|
4 | * The contents of this file are subject to the Mozilla Public License Version
|
---|
5 | * 1.1 (the "License"); you may not use this file except in compliance with
|
---|
6 | * the License. You may obtain a copy of the License at
|
---|
7 | * http://www.mozilla.org/MPL/
|
---|
8 | *
|
---|
9 | * Software distributed under the License is distributed on an "AS IS" basis,
|
---|
10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
---|
11 | * for the specific language governing rights and limitations under the
|
---|
12 | * License.
|
---|
13 | *
|
---|
14 | * The Original Code is Mozilla IPC.
|
---|
15 | *
|
---|
16 | * The Initial Developer of the Original Code is IBM Corporation.
|
---|
17 | * Portions created by the Initial Developer are Copyright (C) 2004
|
---|
18 | * the Initial Developer. All Rights Reserved.
|
---|
19 | *
|
---|
20 | * Contributor(s):
|
---|
21 | * Darin Fisher <darin@meer.net>
|
---|
22 | *
|
---|
23 | * Alternatively, the contents of this file may be used under the terms of
|
---|
24 | * either the GNU General Public License Version 2 or later (the "GPL"), or
|
---|
25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
---|
26 | * in which case the provisions of the GPL or the LGPL are applicable instead
|
---|
27 | * of those above. If you wish to allow use of your version of this file only
|
---|
28 | * under the terms of either the GPL or the LGPL, and not to allow others to
|
---|
29 | * use your version of this file under the terms of the MPL, indicate your
|
---|
30 | * decision by deleting the provisions above and replace them with the notice
|
---|
31 | * and other provisions required by the GPL or the LGPL. If you do not delete
|
---|
32 | * the provisions above, a recipient may use your version of this file under
|
---|
33 | * the terms of any one of the MPL, the GPL or the LGPL.
|
---|
34 | *
|
---|
35 | * ***** END LICENSE BLOCK ***** */
|
---|
36 |
|
---|
37 | #ifndef ipcdclient_h__
|
---|
38 | #define ipcdclient_h__
|
---|
39 |
|
---|
40 | /*****************************************************************************
|
---|
41 | * This file provides a client-side API to the IPC daemon.
|
---|
42 | *
|
---|
43 | * This API can be used to communicate with other clients of the IPC daemon
|
---|
44 | * as well as modules running inside the IPC daemon.
|
---|
45 | *
|
---|
46 | * This API is meant to be used only on the application's main thread. It is
|
---|
47 | * assumed that callbacks can be dispatched via the main thread's event queue.
|
---|
48 | */
|
---|
49 |
|
---|
50 | #include "nscore.h"
|
---|
51 | #include "nsID.h"
|
---|
52 | #include "nsError.h"
|
---|
53 | #include "ipcIMessageObserver.h"
|
---|
54 | #include "ipcIClientObserver.h"
|
---|
55 |
|
---|
56 | /* This API is only provided for the extensions compiled into the IPCDC
|
---|
57 | * library, hence this API is hidden in the final DSO. */
|
---|
58 | #define IPC_METHOD NS_HIDDEN_(nsresult)
|
---|
59 |
|
---|
60 | /* This value can be used to represent the client id of any client connected
|
---|
61 | * to the IPC daemon. */
|
---|
62 | #define IPC_SENDER_ANY PR_UINT32_MAX
|
---|
63 |
|
---|
64 | /* This error code can only be returned by OnMessageAvailable, when called by
|
---|
65 | * IPC_WaitMessage. See IPC_WaitMessage for a description of how this error
|
---|
66 | * code may be used. */
|
---|
67 | #define IPC_WAIT_NEXT_MESSAGE \
|
---|
68 | NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 10)
|
---|
69 |
|
---|
70 | /* This error code is returned by IPC_WaitMessage under certain conditions. */
|
---|
71 | #define IPC_ERROR_WOULD_BLOCK NS_BASE_STREAM_WOULD_BLOCK
|
---|
72 |
|
---|
73 | /*****************************************************************************
|
---|
74 | * Initialization and Shutdown
|
---|
75 | */
|
---|
76 |
|
---|
77 | // XXX limit these to the main thread, and call them from our module's ctor/dtor?
|
---|
78 |
|
---|
79 | /**
|
---|
80 | * Connects this process to the IPC daemon and initializes it for use as a
|
---|
81 | * client of the IPC daemon. This function must be called once before any
|
---|
82 | * other methods defined in this file can be used.
|
---|
83 | *
|
---|
84 | * @returns NS_ERROR_ALREADY_INITIALIZED if IPC_Shutdown was not called since
|
---|
85 | * the last time IPC_Init was called.
|
---|
86 | */
|
---|
87 | IPC_METHOD IPC_Init();
|
---|
88 |
|
---|
89 | /**
|
---|
90 | * Disconnects this process from the IPC daemon. After this function is
|
---|
91 | * called, no other methods in this file except for IPC_Init may be called.
|
---|
92 | *
|
---|
93 | * This function calls all client observers (registered with
|
---|
94 | * IPC_AddClientObserver) before it actually disconnects from the IPC daemon,
|
---|
95 | * with aClientID parameter of the OnClientStateChange callback specially
|
---|
96 | * set to IPC_SENDER_ANY and aClientState set to CLIENT_DOWN. This gives
|
---|
97 | * the interested party an opportunity to perform a proper shutdown procedure.
|
---|
98 | * All IPC methods are still available inside OnClientStateChange call except
|
---|
99 | * the IPC_WaitMessage function, that will immediately fail with an error.
|
---|
100 | * OnClientStateChange is called on the same thread where this function is
|
---|
101 | * called.
|
---|
102 | *
|
---|
103 | * @returns NS_ERROR_NOT_INITIALIZED if IPC_Init has not been called or if
|
---|
104 | * IPC_Init did not return a success code.
|
---|
105 | */
|
---|
106 | IPC_METHOD IPC_Shutdown();
|
---|
107 |
|
---|
108 |
|
---|
109 | /*****************************************************************************
|
---|
110 | * The core messaging API
|
---|
111 | */
|
---|
112 |
|
---|
113 | /**
|
---|
114 | * Call this method to define a message target. A message target is defined
|
---|
115 | * by a UUID and a message observer. This observer is notified asynchronously
|
---|
116 | * whenever a message is sent to this target in this process.
|
---|
117 | *
|
---|
118 | * This function has three main effects:
|
---|
119 | * o If the message target is already defined, then this function simply
|
---|
120 | * resets its message observer.
|
---|
121 | * o If the message target is not already defined, then the message target
|
---|
122 | * is defined and the IPC daemon is notified of the existance of this
|
---|
123 | * message target.
|
---|
124 | * o If null is passed for the message observer, then the message target is
|
---|
125 | * removed, and the daemon is notified of the removal of this message target.
|
---|
126 | *
|
---|
127 | * If aOnCurrentThread is true, then notifications to the observer will occur
|
---|
128 | * on the current thread. This means that there must be a nsIEventTarget
|
---|
129 | * associated with the calling thread. If aOnCurrentThread is false, then
|
---|
130 | * notifications to the observer will occur on a background thread. In which
|
---|
131 | * case, the observer must be threadsafe.
|
---|
132 | */
|
---|
133 | IPC_METHOD IPC_DefineTarget(
|
---|
134 | const nsID &aTarget,
|
---|
135 | ipcIMessageObserver *aObserver,
|
---|
136 | PRBool aOnCurrentThread = PR_TRUE
|
---|
137 | );
|
---|
138 |
|
---|
139 | /**
|
---|
140 | * Call this method to temporarily disable the message observer configured
|
---|
141 | * for a message target.
|
---|
142 | */
|
---|
143 | IPC_METHOD IPC_DisableMessageObserver(
|
---|
144 | const nsID &aTarget
|
---|
145 | );
|
---|
146 |
|
---|
147 | /**
|
---|
148 | * Call this method to re-enable the message observer configured for a
|
---|
149 | * message target.
|
---|
150 | */
|
---|
151 | IPC_METHOD IPC_EnableMessageObserver(
|
---|
152 | const nsID &aTarget
|
---|
153 | );
|
---|
154 |
|
---|
155 | /**
|
---|
156 | * This function sends a message to the IPC daemon asynchronously. If
|
---|
157 | * aReceiverID is non-zero, then the message is forwarded to the client
|
---|
158 | * corresponding to that identifier.
|
---|
159 | *
|
---|
160 | * If there is no client corresponding to aRecieverID, then the IPC daemon will
|
---|
161 | * simply drop the message.
|
---|
162 | */
|
---|
163 | IPC_METHOD IPC_SendMessage(
|
---|
164 | PRUint32 aReceiverID,
|
---|
165 | const nsID &aTarget,
|
---|
166 | const PRUint8 *aData,
|
---|
167 | PRUint32 aDataLen
|
---|
168 | );
|
---|
169 |
|
---|
170 | /**
|
---|
171 | * This function blocks the calling thread until a message for the given target
|
---|
172 | * is received (optionally from the specified client).
|
---|
173 | *
|
---|
174 | * The aSenderID parameter is interpreted as follows:
|
---|
175 | * o If aSenderID is 0, then this function waits for a message to be sent by
|
---|
176 | * the IPC daemon.
|
---|
177 | * o If aSenderID is IPC_SENDER_ANY, then this function waits for a message
|
---|
178 | * to be sent from any source.
|
---|
179 | * o Otherwise, this function waits for a message to be sent by the client
|
---|
180 | * with ID given by aSenderID. If aSenderID does not identify a valid
|
---|
181 | * client, or if the client dies while waiting, then this function will
|
---|
182 | * return an error.
|
---|
183 | *
|
---|
184 | * The aObserver parameter is interpreted as follows:
|
---|
185 | * o If aObserver is null, then the default message observer for the target
|
---|
186 | * is invoked when the next message is received.
|
---|
187 | * o Otherwise, aObserver will be inovked when the next message is received.
|
---|
188 | *
|
---|
189 | * The aConsumer parameter is interpreted as follows:
|
---|
190 | * o If aObserver is null or aConsumer is null, this parameter is ignored.
|
---|
191 | * o Otherwise, aConsumer will be invoked right after (and only if) aObserver
|
---|
192 | * has accepted some message. It will receive exactly the same message
|
---|
193 | * that was accepted by aObserver.
|
---|
194 | *
|
---|
195 | * The aTimeout parameter is interpreted as follows:
|
---|
196 | * o If aTimeout is PR_INTERVAL_NO_TIMEOUT, then this function will block
|
---|
197 | * until a matching message is received.
|
---|
198 | * o If aTimeout is PR_INTERVAL_NO_WAIT, then this function will only inspect
|
---|
199 | * the current queue of messages. If no matching message is found, then
|
---|
200 | * IPC_ERROR_WOULD_BLOCK is returned.
|
---|
201 | * o Otherwise, aTimeout specifies the maximum amount of time to wait for a
|
---|
202 | * matching message to be received. If no matching message is found after
|
---|
203 | * the timeout expires, then IPC_ERROR_WOULD_BLOCK is returned.
|
---|
204 | *
|
---|
205 | * If aObserver's OnMessageAvailable function returns IPC_WAIT_NEXT_MESSAGE,
|
---|
206 | * then the function will continue blocking until the next matching message
|
---|
207 | * is received. Bypassed messages will be dispatched to the default message
|
---|
208 | * observer when the event queue, associated with the thread that called
|
---|
209 | * IPC_DefineTarget, is processed.
|
---|
210 | *
|
---|
211 | * There is a special case if aSenderID is IPC_SENDER_ANY and one of IPC clients
|
---|
212 | * dies while this function waits for a message. In this case, aObserver's
|
---|
213 | * OnMessageAvailable function is called with a special set of arguments:
|
---|
214 | * dead client id, empty target id and null message (both data and data length
|
---|
215 | * are zeroes). If it returns IPC_WAIT_NEXT_MESSAGE, IPC_WaitMessage continues
|
---|
216 | * blocking as usual, otherwise an error is immediately returned to the caller.
|
---|
217 | *
|
---|
218 | * aObserver is not expected to use any IPC system functons from within its
|
---|
219 | * OnMessageAvailable implementation. This is because the IPC system is not
|
---|
220 | * re-entrant during invocation of OnMessageAvailable function, and making other
|
---|
221 | * IPC calls can lead to unexpected results (like message losses or traps). On
|
---|
222 | * the contrary, aConsumer's OnMessageAvailable function is allowed to use the
|
---|
223 | * IPC system without any limitations.
|
---|
224 | *
|
---|
225 | * This function runs the risk of hanging the calling thread indefinitely if
|
---|
226 | * no matching message is ever received.
|
---|
227 | */
|
---|
228 | IPC_METHOD IPC_WaitMessage(
|
---|
229 | PRUint32 aSenderID,
|
---|
230 | const nsID &aTarget,
|
---|
231 | ipcIMessageObserver *aObserver = nsnull,
|
---|
232 | ipcIMessageObserver *aConsumer = nsnull,
|
---|
233 | PRIntervalTime aTimeout = PR_INTERVAL_NO_TIMEOUT
|
---|
234 | );
|
---|
235 |
|
---|
236 | /*****************************************************************************/
|
---|
237 |
|
---|
238 | /**
|
---|
239 | * Returns the "ClientID" of the current process.
|
---|
240 | */
|
---|
241 | IPC_METHOD IPC_GetID(
|
---|
242 | PRUint32 *aClientID
|
---|
243 | );
|
---|
244 |
|
---|
245 | /**
|
---|
246 | * Adds a new name for the current process. The IPC daemon is notified of this
|
---|
247 | * change, which allows other processes to discover this process by the given
|
---|
248 | * name.
|
---|
249 | */
|
---|
250 | IPC_METHOD IPC_AddName(
|
---|
251 | const char *aName
|
---|
252 | );
|
---|
253 |
|
---|
254 | /**
|
---|
255 | * Removes a name associated with the current process.
|
---|
256 | */
|
---|
257 | IPC_METHOD IPC_RemoveName(
|
---|
258 | const char *aName
|
---|
259 | );
|
---|
260 |
|
---|
261 | /**
|
---|
262 | * Adds client observer. Will be called on the main thread.
|
---|
263 | */
|
---|
264 | IPC_METHOD IPC_AddClientObserver(
|
---|
265 | ipcIClientObserver *aObserver
|
---|
266 | );
|
---|
267 |
|
---|
268 | /**
|
---|
269 | * Removes client observer.
|
---|
270 | */
|
---|
271 | IPC_METHOD IPC_RemoveClientObserver(
|
---|
272 | ipcIClientObserver *aObserver
|
---|
273 | );
|
---|
274 |
|
---|
275 | /**
|
---|
276 | * Resolves the given client name to a client ID of a process connected to
|
---|
277 | * the IPC daemon.
|
---|
278 | */
|
---|
279 | IPC_METHOD IPC_ResolveClientName(
|
---|
280 | const char *aName,
|
---|
281 | PRUint32 *aClientID
|
---|
282 | );
|
---|
283 |
|
---|
284 | /**
|
---|
285 | * Tests whether the client is connected to the IPC daemon.
|
---|
286 | */
|
---|
287 | IPC_METHOD IPC_ClientExists(
|
---|
288 | PRUint32 aClientID,
|
---|
289 | PRBool *aResult
|
---|
290 | );
|
---|
291 |
|
---|
292 | /*****************************************************************************/
|
---|
293 |
|
---|
294 | /**
|
---|
295 | * This class can be used to temporarily disable the default message observer
|
---|
296 | * defined for a particular message target.
|
---|
297 | */
|
---|
298 | class ipcDisableMessageObserverForScope
|
---|
299 | {
|
---|
300 | public:
|
---|
301 | ipcDisableMessageObserverForScope(const nsID &aTarget)
|
---|
302 | : mTarget(aTarget)
|
---|
303 | {
|
---|
304 | IPC_DisableMessageObserver(mTarget);
|
---|
305 | }
|
---|
306 |
|
---|
307 | ~ipcDisableMessageObserverForScope()
|
---|
308 | {
|
---|
309 | IPC_EnableMessageObserver(mTarget);
|
---|
310 | }
|
---|
311 |
|
---|
312 | private:
|
---|
313 | const nsID &mTarget;
|
---|
314 | };
|
---|
315 |
|
---|
316 | #define IPC_DISABLE_MESSAGE_OBSERVER_FOR_SCOPE(_t) \
|
---|
317 | ipcDisableMessageObserverForScope ipc_dmo_for_scope##_t(_t)
|
---|
318 |
|
---|
319 | #endif /* ipcdclient_h__ */
|
---|