VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcdclient.h@ 30052

Last change on this file since 30052 was 30052, checked in by vboxsync, 15 years ago

xpcom/ipcd: Fix message processing so that IPCM client up/down messages are not piled up in the dconnect message queue. Mainly involved converting the boolean wait/process message handling logic to a tri-state wait/process/discard style. The IPCM messages can now be processed without being passed to the DConnect message processing logic.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
Line 
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#ifdef VBOX
71/* This error code can only be returned by the selector functions called by
72 * WaitTarget. The message should be dropped without processing. */
73#define IPC_DISCARD_MESSAGE \
74 NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 12)
75#endif /* VBOX */
76
77/* This error code is returned by IPC_WaitMessage under certain conditions. */
78#define IPC_ERROR_WOULD_BLOCK NS_BASE_STREAM_WOULD_BLOCK
79
80/*****************************************************************************
81 * Initialization and Shutdown
82 */
83
84// XXX limit these to the main thread, and call them from our module's ctor/dtor?
85
86/**
87 * Connects this process to the IPC daemon and initializes it for use as a
88 * client of the IPC daemon. This function must be called once before any
89 * other methods defined in this file can be used.
90 *
91 * @returns NS_ERROR_ALREADY_INITIALIZED if IPC_Shutdown was not called since
92 * the last time IPC_Init was called.
93 */
94IPC_METHOD IPC_Init();
95
96/**
97 * Disconnects this process from the IPC daemon. After this function is
98 * called, no other methods in this file except for IPC_Init may be called.
99 *
100 * This function calls all client observers (registered with
101 * IPC_AddClientObserver) before it actually disconnects from the IPC daemon,
102 * with aClientID parameter of the OnClientStateChange callback specially
103 * set to IPC_SENDER_ANY and aClientState set to CLIENT_DOWN. This gives
104 * the interested party an opportunity to perform a proper shutdown procedure.
105 * All IPC methods are still available inside OnClientStateChange call except
106 * the IPC_WaitMessage function, that will immediately fail with an error.
107 * OnClientStateChange is called on the same thread where this function is
108 * called.
109 *
110 * @returns NS_ERROR_NOT_INITIALIZED if IPC_Init has not been called or if
111 * IPC_Init did not return a success code.
112 */
113IPC_METHOD IPC_Shutdown();
114
115
116/*****************************************************************************
117 * The core messaging API
118 */
119
120/**
121 * Call this method to define a message target. A message target is defined
122 * by a UUID and a message observer. This observer is notified asynchronously
123 * whenever a message is sent to this target in this process.
124 *
125 * This function has three main effects:
126 * o If the message target is already defined, then this function simply
127 * resets its message observer.
128 * o If the message target is not already defined, then the message target
129 * is defined and the IPC daemon is notified of the existance of this
130 * message target.
131 * o If null is passed for the message observer, then the message target is
132 * removed, and the daemon is notified of the removal of this message target.
133 *
134 * If aOnCurrentThread is true, then notifications to the observer will occur
135 * on the current thread. This means that there must be a nsIEventTarget
136 * associated with the calling thread. If aOnCurrentThread is false, then
137 * notifications to the observer will occur on a background thread. In which
138 * case, the observer must be threadsafe.
139 */
140IPC_METHOD IPC_DefineTarget(
141 const nsID &aTarget,
142 ipcIMessageObserver *aObserver,
143 PRBool aOnCurrentThread = PR_TRUE
144);
145
146/**
147 * Call this method to temporarily disable the message observer configured
148 * for a message target.
149 */
150IPC_METHOD IPC_DisableMessageObserver(
151 const nsID &aTarget
152);
153
154/**
155 * Call this method to re-enable the message observer configured for a
156 * message target.
157 */
158IPC_METHOD IPC_EnableMessageObserver(
159 const nsID &aTarget
160);
161
162/**
163 * This function sends a message to the IPC daemon asynchronously. If
164 * aReceiverID is non-zero, then the message is forwarded to the client
165 * corresponding to that identifier.
166 *
167 * If there is no client corresponding to aRecieverID, then the IPC daemon will
168 * simply drop the message.
169 */
170IPC_METHOD IPC_SendMessage(
171 PRUint32 aReceiverID,
172 const nsID &aTarget,
173 const PRUint8 *aData,
174 PRUint32 aDataLen
175);
176
177/**
178 * This function blocks the calling thread until a message for the given target
179 * is received (optionally from the specified client).
180 *
181 * The aSenderID parameter is interpreted as follows:
182 * o If aSenderID is 0, then this function waits for a message to be sent by
183 * the IPC daemon.
184 * o If aSenderID is IPC_SENDER_ANY, then this function waits for a message
185 * to be sent from any source.
186 * o Otherwise, this function waits for a message to be sent by the client
187 * with ID given by aSenderID. If aSenderID does not identify a valid
188 * client, or if the client dies while waiting, then this function will
189 * return an error.
190 *
191 * The aObserver parameter is interpreted as follows:
192 * o If aObserver is null, then the default message observer for the target
193 * is invoked when the next message is received.
194 * o Otherwise, aObserver will be inovked when the next message is received.
195 *
196 * The aConsumer parameter is interpreted as follows:
197 * o If aObserver is null or aConsumer is null, this parameter is ignored.
198 * o Otherwise, aConsumer will be invoked right after (and only if) aObserver
199 * has accepted some message. It will receive exactly the same message
200 * that was accepted by aObserver.
201 *
202 * The aTimeout parameter is interpreted as follows:
203 * o If aTimeout is PR_INTERVAL_NO_TIMEOUT, then this function will block
204 * until a matching message is received.
205 * o If aTimeout is PR_INTERVAL_NO_WAIT, then this function will only inspect
206 * the current queue of messages. If no matching message is found, then
207 * IPC_ERROR_WOULD_BLOCK is returned.
208 * o Otherwise, aTimeout specifies the maximum amount of time to wait for a
209 * matching message to be received. If no matching message is found after
210 * the timeout expires, then IPC_ERROR_WOULD_BLOCK is returned.
211 *
212 * If aObserver's OnMessageAvailable function returns IPC_WAIT_NEXT_MESSAGE,
213 * then the function will continue blocking until the next matching message
214 * is received. Bypassed messages will be dispatched to the default message
215 * observer when the event queue, associated with the thread that called
216 * IPC_DefineTarget, is processed.
217 *
218 * There is a special case if aSenderID is IPC_SENDER_ANY and one of IPC clients
219 * dies while this function waits for a message. In this case, aObserver's
220 * OnMessageAvailable function is called with a special set of arguments:
221 * dead client id, empty target id and null message (both data and data length
222 * are zeroes). If it returns IPC_WAIT_NEXT_MESSAGE, IPC_WaitMessage continues
223 * blocking as usual, otherwise an error is immediately returned to the caller.
224 *
225 * aObserver is not expected to use any IPC system functons from within its
226 * OnMessageAvailable implementation. This is because the IPC system is not
227 * re-entrant during invocation of OnMessageAvailable function, and making other
228 * IPC calls can lead to unexpected results (like message losses or traps). On
229 * the contrary, aConsumer's OnMessageAvailable function is allowed to use the
230 * IPC system without any limitations.
231 *
232 * This function runs the risk of hanging the calling thread indefinitely if
233 * no matching message is ever received.
234 */
235IPC_METHOD IPC_WaitMessage(
236 PRUint32 aSenderID,
237 const nsID &aTarget,
238 ipcIMessageObserver *aObserver = nsnull,
239 ipcIMessageObserver *aConsumer = nsnull,
240 PRIntervalTime aTimeout = PR_INTERVAL_NO_TIMEOUT
241);
242
243/*****************************************************************************/
244
245/**
246 * Returns the "ClientID" of the current process.
247 */
248IPC_METHOD IPC_GetID(
249 PRUint32 *aClientID
250);
251
252/**
253 * Adds a new name for the current process. The IPC daemon is notified of this
254 * change, which allows other processes to discover this process by the given
255 * name.
256 */
257IPC_METHOD IPC_AddName(
258 const char *aName
259);
260
261/**
262 * Removes a name associated with the current process.
263 */
264IPC_METHOD IPC_RemoveName(
265 const char *aName
266);
267
268/**
269 * Adds client observer. Will be called on the main thread.
270 */
271IPC_METHOD IPC_AddClientObserver(
272 ipcIClientObserver *aObserver
273);
274
275/**
276 * Removes client observer.
277 */
278IPC_METHOD IPC_RemoveClientObserver(
279 ipcIClientObserver *aObserver
280);
281
282/**
283 * Resolves the given client name to a client ID of a process connected to
284 * the IPC daemon.
285 */
286IPC_METHOD IPC_ResolveClientName(
287 const char *aName,
288 PRUint32 *aClientID
289);
290
291/**
292 * Tests whether the client is connected to the IPC daemon.
293 */
294IPC_METHOD IPC_ClientExists(
295 PRUint32 aClientID,
296 PRBool *aResult
297);
298
299/*****************************************************************************/
300
301/**
302 * This class can be used to temporarily disable the default message observer
303 * defined for a particular message target.
304 */
305class ipcDisableMessageObserverForScope
306{
307public:
308 ipcDisableMessageObserverForScope(const nsID &aTarget)
309 : mTarget(aTarget)
310 {
311 IPC_DisableMessageObserver(mTarget);
312 }
313
314 ~ipcDisableMessageObserverForScope()
315 {
316 IPC_EnableMessageObserver(mTarget);
317 }
318
319private:
320 const nsID &mTarget;
321};
322
323#define IPC_DISABLE_MESSAGE_OBSERVER_FOR_SCOPE(_t) \
324 ipcDisableMessageObserverForScope ipc_dmo_for_scope##_t(_t)
325
326#endif /* ipcdclient_h__ */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette