Changeset 103472 in vbox for trunk/src/libs/xpcom18a4/ipc
- Timestamp:
- Feb 20, 2024 9:26:18 AM (12 months ago)
- svn:sync-xref-src-repo-rev:
- 161808
- Location:
- trunk/src/libs/xpcom18a4/ipc/ipcd
- Files:
-
- 6 deleted
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcIService.idl
r1 r103472 118 118 */ 119 119 unsigned long resolveClientName(in string aName); 120 121 122 /**123 * tests whether a particular client is connected to the IPC daemon.124 */125 boolean clientExists(in unsigned long aClientID);126 120 127 121 -
trunk/src/libs/xpcom18a4/ipc/ipcd/client/public/ipcdclient.h
r102470 r103472 291 291 ); 292 292 293 /**294 * Tests whether the client is connected to the IPC daemon.295 */296 IPC_METHOD IPC_ClientExists(297 PRUint32 aClientID,298 PRBool *aResult299 );300 301 293 /*****************************************************************************/ 302 294 -
trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcConnection.h
r1 r103472 40 40 41 41 #include "nscore.h" 42 43 class ipcMessage; 42 #include "ipcMessageNew.h" 44 43 45 44 #define IPC_METHOD_PRIVATE_(type) NS_HIDDEN_(type) … … 88 87 * NOTE: This function may be called on any thread. 89 88 */ 90 IPC_METHOD_PRIVATE IPC_SendMsg( ipcMessage *msg);89 IPC_METHOD_PRIVATE IPC_SendMsg(PIPCMSG pMsg); 91 90 92 91 /** … … 140 139 * 141 140 * This function is called whenever an incoming message is read from the IPC 142 * daemon. The i pcMessage object, |msg|, must be deleted by the implementation143 * of IPC_OnMessageAvailable when the object is no longer needed.141 * daemon. The implementer of this method must not assume ownership over the 142 * message. 144 143 */ 145 IPC_METHOD_PRIVATE_(void) IPC_OnMessageAvailable(ipcMessage *msg); 144 DECLHIDDEN(void) IPC_OnMessageAvailable(PCIPCMSG pMsg); 145 146 /** 147 * IPC_MsgFree 148 * 149 * This function is called whenever an outgoing message was sent by the 150 * connection code and the message can be freed. 151 */ 152 DECLHIDDEN(void) IPC_MsgFree(PIPCMSG pMsg); 146 153 147 154 #endif // ipcConnection_h__ -
trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcConnectionUnix.cpp
r102060 r103472 39 39 #include <iprt/err.h> 40 40 #include <iprt/env.h> 41 #include <iprt/list.h> 41 42 #include <iprt/mem.h> 42 43 #include <iprt/pipe.h> … … 57 58 58 59 #include "ipcConnection.h" 59 #include "ipcMessageQ.h" 60 #include "ipcMessageNew.h" 61 #include "ipcList.h" 60 62 #include "ipcConfig.h" 61 63 … … 129 131 RTPOLLSET hPollSet; 130 132 ipcCallbackQ callback_queue; 131 ipcMessageQ send_queue;132 PRUint32 send_offset; // amount of send_queue.First() already written.133 ipcMessage *in_msg;134 133 bool fShutdown; 134 /** The list of messages waiting for sending out. */ 135 RTLISTANCHOR LstMsgsOut; 136 /** Number of bytes in the message of the first message on the list which was already sent. */ 137 size_t offSendFirst; 138 /** The message currently being received. */ 139 IPCMSG MsgIn; 135 140 }; 136 141 … … 146 151 RTSocketClose(s->hSockConn); 147 152 148 if (s->in_msg) 149 delete s->in_msg; 150 151 s->send_queue.DeleteAll(); 153 IPCMsgFree(&s->MsgIn, false /*fFreeStruct*/); 154 155 PIPCMSG pIt, pItNext; 156 RTListForEachSafe(&s->LstMsgsOut, pIt, pItNext, IPCMSG, NdMsg) 157 { 158 RTListNodeRemove(&pIt->NdMsg); 159 IPCMsgFree(pIt, true /*fFreeStruct*/); 160 } 161 152 162 RTMemFree(s); 153 163 } … … 159 169 return NULL; 160 170 161 s->send_offset = 0;162 s-> in_msg = NULL;163 s->fShutdown = false;164 165 int vrc = RTCritSectInit(&s->CritSect);171 RTListInit(&s->LstMsgsOut); 172 s->offSendFirst = 0; 173 s->fShutdown = false; 174 175 int vrc = IPCMsgInit(&s->MsgIn, 0 /*cbBuf*/); 166 176 if (RT_SUCCESS(vrc)) 167 177 { 168 vrc = RT PollSetCreate(&s->hPollSet);178 vrc = RTCritSectInit(&s->CritSect); 169 179 if (RT_SUCCESS(vrc)) 170 180 { 171 RTPIPE hPipeR; 172 173 vrc = RTPipeCreate(&s->hWakeupPipeR, &s->hWakeupPipeW, 0 /*fFlags*/); 181 vrc = RTPollSetCreate(&s->hPollSet); 174 182 if (RT_SUCCESS(vrc)) 175 183 { 176 vrc = RTP ollSetAddSocket(s->hPollSet, hSockConn, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, SOCK);184 vrc = RTPipeCreate(&s->hWakeupPipeR, &s->hWakeupPipeW, 0 /*fFlags*/); 177 185 if (RT_SUCCESS(vrc)) 178 186 { 179 vrc = RTPollSetAdd Pipe(s->hPollSet, s->hWakeupPipeR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, POLL);187 vrc = RTPollSetAddSocket(s->hPollSet, hSockConn, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, SOCK); 180 188 if (RT_SUCCESS(vrc)) 181 189 { 182 vrc = RT SocketSetInheritance(hSockConn, false /*fInheritable*/);190 vrc = RTPollSetAddPipe(s->hPollSet, s->hWakeupPipeR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, POLL); 183 191 if (RT_SUCCESS(vrc)) 184 192 { 185 s->hSockConn = hSockConn; 186 return s; 193 vrc = RTSocketSetInheritance(hSockConn, false /*fInheritable*/); 194 if (RT_SUCCESS(vrc)) 195 { 196 s->hSockConn = hSockConn; 197 return s; 198 } 199 200 LogFlowFunc(("coudn't make IPC socket non-inheritable [err=%Rrc]\n", vrc)); 201 vrc = RTPollSetRemove(s->hPollSet, POLL); AssertRC(vrc); 187 202 } 188 203 189 LogFlowFunc(("coudn't make IPC socket non-inheritable [err=%Rrc]\n", vrc)); 190 vrc = RTPollSetRemove(s->hPollSet, POLL); AssertRC(vrc); 204 vrc = RTPollSetRemove(s->hPollSet, SOCK); AssertRC(vrc); 191 205 } 192 206 193 vrc = RTPollSetRemove(s->hPollSet, SOCK); AssertRC(vrc); 207 vrc = RTPipeClose(s->hWakeupPipeR); AssertRC(vrc); 208 vrc = RTPipeClose(s->hWakeupPipeW); AssertRC(vrc); 194 209 } 195 210 196 vrc = RTPipeClose(s->hWakeupPipeR); AssertRC(vrc); 197 vrc = RTPipeClose(s->hWakeupPipeW); AssertRC(vrc); 198 } 199 200 vrc = RTPollSetDestroy(s->hPollSet); AssertRC(vrc); 201 } 202 203 RTCritSectDelete(&s->CritSect); 211 vrc = RTPollSetDestroy(s->hPollSet); AssertRC(vrc); 212 } 213 214 RTCritSectDelete(&s->CritSect); 215 } 216 217 IPCMsgFree(&s->MsgIn, false /*fFreeStruct*/); 204 218 } 205 219 … … 236 250 while (cbRead) 237 251 { 238 PRUint32 bytesRead; 239 PRBool fComplete = PR_FALSE; 240 241 /* No message frame available? Allocate a new one. */ 242 if (!s->in_msg) 243 { 244 s->in_msg = new ipcMessage; 245 if (RT_UNLIKELY(!s->in_msg)) 246 { 247 rv = NS_ERROR_OUT_OF_MEMORY; 248 break; 249 } 250 } 251 252 if (s->in_msg->ReadFrom(pdata, cbRead, &bytesRead, &fComplete) != PR_SUCCESS) 252 size_t cbProcessed = 0; 253 bool fComplete = false; 254 255 if (IPCMsgReadFrom(&s->MsgIn, pdata, cbRead, &cbProcessed, &fComplete) != VINF_SUCCESS) 253 256 { 254 257 LogFlowFunc(("error reading IPC message\n")); … … 257 260 } 258 261 259 Assert(cbRead >= bytesRead);260 cbRead -= bytesRead;261 pdata += bytesRead;262 Assert(cbRead >= cbProcessed); 263 cbRead -= cbProcessed; 264 pdata += cbProcessed; 262 265 263 266 if (fComplete) 264 267 { 265 // protect against weird re-entrancy cases... 266 ipcMessage *m = s->in_msg; 267 s->in_msg = NULL; 268 269 IPC_OnMessageAvailable(m); 268 IPC_OnMessageAvailable(&s->MsgIn); 269 IPCMsgReset(&s->MsgIn); 270 270 } 271 271 } … … 281 281 RTCritSectEnter(&s->CritSect); 282 282 283 / / write one message and then return.284 if (s->send_queue.First())283 /* Write as much as we can. */ 284 while (!RTListIsEmpty(&s->LstMsgsOut)) 285 285 { 286 286 size_t cbWritten = 0; 287 PIPCMSG pMsg = RTListGetFirst(&s->LstMsgsOut, IPCMSG, NdMsg); 287 288 int vrc = RTSocketWriteNB(s->hSockConn, 288 s->send_queue.First()->MsgBuf() + s->send_offset,289 s->send_queue.First()->MsgLen() - s->send_offset,289 (const uint8_t *)IPCMsgGetBuf(pMsg) + s->offSendFirst, 290 IPCMsgGetSize(pMsg) - s->offSendFirst, 290 291 &cbWritten); 291 292 if (vrc == VINF_SUCCESS && cbWritten) 292 293 { 293 s->send_offset += cbWritten; 294 if (s->send_offset == s->send_queue.First()->MsgLen()) 295 { 296 s->send_queue.DeleteFirst(); 297 s->send_offset = 0; 298 299 /* if the send queue is empty, then we need to stop trying to write. */ 300 if (s->send_queue.IsEmpty()) 301 { 302 vrc = RTPollSetEventsChange(s->hPollSet, SOCK, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR); 303 AssertRC(vrc); 304 } 305 } 306 } 307 else if (vrc != VINF_TRY_AGAIN) 294 s->offSendFirst += cbWritten; 295 if (s->offSendFirst == IPCMsgGetSize(pMsg)) 296 { 297 RTListNodeRemove(&pMsg->NdMsg); 298 IPC_MsgFree(pMsg); 299 s->offSendFirst = 0; 300 } 301 } 302 else if (vrc == VINF_TRY_AGAIN) 303 break; 304 else 308 305 { 309 306 Assert(RT_FAILURE(vrc)); … … 311 308 rv = NS_ERROR_UNEXPECTED; 312 309 } 310 } 311 312 /* if the send queue is empty, then we need to stop trying to write. */ 313 if (RTListIsEmpty(&s->LstMsgsOut)) 314 { 315 int vrc = RTPollSetEventsChange(s->hPollSet, SOCK, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR); 316 AssertRC(vrc); 313 317 } 314 318 … … 375 379 RTCritSectEnter(&s->CritSect); 376 380 377 if (! s->send_queue.IsEmpty())381 if (!RTListIsEmpty(&s->LstMsgsOut)) 378 382 { 379 383 vrc = RTPollSetEventsChange(s->hPollSet, SOCK, RTPOLL_EVT_READ | RTPOLL_EVT_WRITE | RTPOLL_EVT_ERROR); … … 387 391 // request until after all queued up messages have been sent and until 388 392 // after all queued up callbacks have been run. 389 if (s->fShutdown && s->send_queue.IsEmpty() && s->callback_queue.IsEmpty())393 if (s->fShutdown && RTListIsEmpty(&s->LstMsgsOut) && s->callback_queue.IsEmpty()) 390 394 rv = NS_ERROR_ABORT; 391 395 … … 559 563 } 560 564 561 nsresult IPC_SendMsg( ipcMessage *msg)565 nsresult IPC_SendMsg(PIPCMSG pMsg) 562 566 { 563 567 if (!gConnState || !gConnThread) … … 565 569 566 570 RTCritSectEnter(&gConnState->CritSect); 567 gConnState->send_queue.Append(msg);571 RTListAppend(&gConnState->LstMsgsOut, &pMsg->NdMsg); 568 572 size_t cbWrittenIgn = 0; 569 573 int vrc = RTPipeWrite(gConnState->hWakeupPipeW, &magicChar, sizeof(magicChar), &cbWrittenIgn); -
trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcService.cpp
r102470 r103472 79 79 } 80 80 81 #if 0 /*unused*/ 81 82 NS_IMETHODIMP 82 83 ipcService::ClientExists(PRUint32 aClientID, PRBool *aResult) … … 84 85 return IPC_ClientExists(aClientID, aResult); 85 86 } 87 #endif 86 88 87 89 NS_IMETHODIMP -
trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
r103331 r103472 39 39 #include "ipcConnection.h" 40 40 #include "ipcConfig.h" 41 #include "ipcMessageQ.h"42 #include "ipcMessageUtils.h"43 41 #include "ipcm.h" 44 42 … … 91 89 92 90 // incoming messages are added to this list 93 ipcMessageQ pendingQ;91 RTLISTANCHOR LstPendingMsgs; 94 92 95 93 // non-zero if the observer has been disabled (this means that new messages … … 104 102 , observerDisabled(0) 105 103 , refcnt(0) 106 {} 104 { 105 RTListInit(&LstPendingMsgs); 106 } 107 107 108 108 ~ipcTargetData() … … 110 110 if (monitor) 111 111 nsAutoMonitor::DestroyMonitor(monitor); 112 113 /* Free all the pending messages. */ 114 PIPCMSG pIt, pItNext; 115 RTListForEachSafe(&LstPendingMsgs, pIt, pItNext, IPCMSG, NdMsg) 116 { 117 RTListNodeRemove(&pIt->NdMsg); 118 IPCMsgFree(pIt, true /*fFreeStruct*/); 119 } 112 120 } 113 121 … … 153 161 { 154 162 RTCritSectRwDelete(&critSect); 163 RTCritSectDelete(&CritSectCache); 164 165 /* Free all the cached messages. */ 166 PIPCMSG pIt, pItNext; 167 RTListForEachSafe(&LstMsgCache, pIt, pItNext, IPCMSG, NdMsg) 168 { 169 RTListNodeRemove(&pIt->NdMsg); 170 IPCMsgFree(pIt, true /*fFreeStruct*/); 171 } 155 172 } 156 173 … … 165 182 nsCOMArray<ipcIClientObserver> clientObservers; 166 183 184 RTCRITSECT CritSectCache; 185 RTLISTANCHOR LstMsgCache; 186 uint32_t cMsgsInCache; 187 167 188 private: 168 189 … … 174 195 /* Not employing the lock validator here to keep performance up in debug builds. */ 175 196 RTCritSectRwInitEx(&critSect, RTCRITSECT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL); 197 198 RTCritSectInit(&CritSectCache); 199 RTListInit(&LstMsgCache); 200 cMsgsInCache = 0; 176 201 } 177 202 }; … … 196 221 197 222 static ipcClientState *gClientState; 223 224 DECLHIDDEN(void) IPC_MsgFree(PIPCMSG pMsg) 225 { 226 if (pMsg->fStack) 227 return; 228 229 int vrc = RTCritSectTryEnter(&gClientState->CritSectCache); 230 if (RT_SUCCESS(vrc)) 231 { 232 if (gClientState->cMsgsInCache < 10) 233 { 234 RTListAppend(&gClientState->LstMsgCache, &pMsg->NdMsg); 235 gClientState->cMsgsInCache++; 236 RTCritSectLeave(&gClientState->CritSectCache); 237 return; 238 } 239 240 RTCritSectLeave(&gClientState->CritSectCache); 241 } 242 243 IPCMsgFree(pMsg, true /*fFreeStruct*/); 244 } 245 246 DECLINLINE(PIPCMSG) ipcdMsgGetFromCache(void) 247 { 248 PIPCMSG pMsg = NULL; 249 250 if (gClientState->cMsgsInCache) 251 { 252 int vrc = RTCritSectTryEnter(&gClientState->CritSectCache); 253 if (RT_SUCCESS(vrc)) 254 { 255 if (gClientState->cMsgsInCache) 256 { 257 pMsg = RTListRemoveFirst(&gClientState->LstMsgCache, IPCMSG, NdMsg); 258 gClientState->cMsgsInCache--; 259 } 260 261 RTCritSectLeave(&gClientState->CritSectCache); 262 } 263 } 264 265 return pMsg; 266 } 267 268 static PIPCMSG IPC_MsgClone(PCIPCMSG pMsg) 269 { 270 PIPCMSG pClone = ipcdMsgGetFromCache(); 271 if (pClone) 272 { 273 int vrc = IPCMsgCloneWithMsg(pMsg, pClone); 274 if (RT_SUCCESS(vrc)) 275 return pClone; 276 277 /* Don't bother putting the clone back into the cache. */ 278 IPCMsgFree(pClone, true /*fFreeStruct*/); 279 } 280 281 /* Allocate new */ 282 return IPCMsgClone(pMsg); 283 } 284 285 static PIPCMSG IPC_MsgNewSg(const nsID &target, size_t cbTotal, PCRTSGSEG paSegs, uint32_t cSegs) 286 { 287 PIPCMSG pMsg = ipcdMsgGetFromCache(); 288 if (pMsg) 289 { 290 int vrc = IPCMsgInitSg(pMsg, target, cbTotal, paSegs, cSegs); 291 if (RT_SUCCESS(vrc)) 292 return pMsg; 293 } 294 295 return IPCMsgNewSg(target, cbTotal, paSegs, cSegs); 296 } 297 198 298 199 299 static PRBool … … 247 347 ProcessPendingQ(const nsID &aTarget) 248 348 { 249 ipcMessageQ tempQ; 250 251 nsRefPtr<ipcTargetData> td; 252 if (GetTarget(aTarget, getter_AddRefs(td))) 253 { 254 nsAutoMonitor mon(td->monitor); 255 256 // if the observer for this target has been temporarily disabled, then 257 // we must not processing any pending messages at this time. 258 259 if (!td->observerDisabled) 260 td->pendingQ.MoveTo(tempQ); 261 } 262 263 // process pending queue outside monitor 264 while (!tempQ.IsEmpty()) 265 { 266 ipcMessage *msg = tempQ.First(); 267 268 // it is possible that messages for other targets are in the queue 269 // (currently, this can be only a IPCM_MSG_PSH_CLIENT_STATE message 270 // initially addressed to IPCM_TARGET, see IPC_OnMessageAvailable()) 271 // --ignore them. 272 if (td->observer && msg->Target().Equals(aTarget)) 273 td->observer->OnMessageAvailable(msg->mMetaData, 274 msg->Target(), 275 (const PRUint8 *) msg->Data(), 276 msg->DataLen()); 277 else 278 { 279 // the IPCM target does not have an observer, and therefore any IPCM 280 // messages that make it here will simply be dropped. 281 NS_ASSERTION(aTarget.Equals(IPCM_TARGET) || msg->Target().Equals(IPCM_TARGET), 282 "unexpected target"); 283 Log(("dropping IPCM message: type=%x\n", IPCM_GetType(msg))); 284 } 285 tempQ.DeleteFirst(); 286 } 349 RTLISTANCHOR LstPendingMsgs; 350 RTListInit(&LstPendingMsgs); 351 352 nsRefPtr<ipcTargetData> td; 353 if (GetTarget(aTarget, getter_AddRefs(td))) 354 { 355 nsAutoMonitor mon(td->monitor); 356 357 // if the observer for this target has been temporarily disabled, then 358 // we must not processing any pending messages at this time. 359 360 if (!td->observerDisabled) 361 RTListMove(&LstPendingMsgs, &td->LstPendingMsgs); 362 } 363 364 // process pending queue outside monitor 365 while (!RTListIsEmpty(&LstPendingMsgs)) 366 { 367 PIPCMSG pMsg = RTListGetFirst(&LstPendingMsgs, IPCMSG, NdMsg); 368 RTListNodeRemove(&pMsg->NdMsg); 369 370 // it is possible that messages for other targets are in the queue 371 // (currently, this can be only a IPCM_MSG_PSH_CLIENT_STATE message 372 // initially addressed to IPCM_TARGET, see IPC_OnMessageAvailable()) 373 // --ignore them. 374 if (td->observer && IPCMsgGetTarget(pMsg)->Equals(aTarget)) 375 td->observer->OnMessageAvailable(pMsg->upUser, 376 *IPCMsgGetTarget(pMsg), 377 (const PRUint8 *)IPCMsgGetPayload(pMsg), 378 IPCMsgGetPayloadSize(pMsg)); 379 else 380 { 381 // the IPCM target does not have an observer, and therefore any IPCM 382 // messages that make it here will simply be dropped. 383 NS_ASSERTION( aTarget.Equals(IPCM_TARGET) 384 || IPCMsgGetTarget(pMsg)->Equals(IPCM_TARGET), 385 "unexpected target"); 386 Log(("dropping IPCM message: type=%x\n", IPCM_GetType(pMsg))); 387 } 388 IPC_MsgFree(pMsg); 389 } 287 390 } 288 391 … … 292 395 // message target. the selector is called while inside the target's monitor. 293 396 294 typedef nsresult (* ipcMessageSelector)( 295 void *arg, 296 ipcTargetData *td, 297 const ipcMessage *msg 298 ); 397 typedef nsresult (* ipcMessageSelector)(void *arg, ipcTargetData *td, PCIPCMSG pMsg); 299 398 300 399 // selects any 301 static nsresult 302 DefaultSelector(void *arg, ipcTargetData *td, const ipcMessage *msg) 400 static nsresult DefaultSelector(void *arg, ipcTargetData *td, PCIPCMSG pMsg) 303 401 { 304 402 return NS_OK; … … 308 406 WaitTarget(const nsID &aTarget, 309 407 RTMSINTERVAL aTimeout, 310 ipcMessage **aMsg,408 PIPCMSG *ppMsg, 311 409 ipcMessageSelector aSelector = nsnull, 312 410 void *aArg = nsnull) 313 411 { 314 * aMsg = nsnull;412 *ppMsg = NULL; 315 413 316 414 if (!aSelector) … … 338 436 } 339 437 340 ipcMessage *lastChecked = nsnull, *beforeLastChecked = nsnull;341 438 nsresult rv = NS_ERROR_ABORT; 342 439 … … 350 447 while (gClientState->connected && (!gClientState->shutdown || isIPCMTarget)) 351 448 { 352 NS_ASSERTION(!lastChecked, "oops");353 354 449 // 355 450 // NOTE: … … 365 460 // 366 461 367 lastChecked = td->pendingQ.First(); 368 beforeLastChecked = nsnull; 369 462 PIPCMSG pIt, pItNext; 370 463 // loop over pending queue until we find a message that our selector likes. 371 while (lastChecked)464 RTListForEachSafe(&td->LstPendingMsgs, pIt, pItNext, IPCMSG, NdMsg) 372 465 { 373 466 // … … 378 471 // to guarantee that every message is processed only once. 379 472 // 380 381 if (!lastChecked->TestFlag(IPC_MSG_FLAG_IN_PROCESS)) 473 if (!IPCMsgIsFlagSet(pIt, IPC_MSG_HDR_FLAG_IN_PROCESS)) 382 474 { 383 lastChecked->SetFlag(IPC_MSG_FLAG_IN_PROCESS);384 nsresult acceptedRV = (aSelector)(aArg, td, lastChecked);385 lastChecked->ClearFlag(IPC_MSG_FLAG_IN_PROCESS);475 IPCMsgSetFlag(pIt, IPC_MSG_HDR_FLAG_IN_PROCESS); 476 nsresult acceptedRV = (aSelector)(aArg, td, pIt); 477 IPCMsgClearFlag(pIt, IPC_MSG_HDR_FLAG_IN_PROCESS); 386 478 387 479 if (acceptedRV != IPC_WAIT_NEXT_MESSAGE) … … 390 482 { 391 483 // remove from pending queue 392 if (beforeLastChecked) 393 td->pendingQ.RemoveAfter(beforeLastChecked); 394 else 395 td->pendingQ.RemoveFirst(); 396 397 lastChecked->mNext = nsnull; 398 *aMsg = lastChecked; 484 RTListNodeRemove(&pIt->NdMsg); 485 *ppMsg = pIt; 399 486 break; 400 487 } 401 488 else /* acceptedRV == IPC_DISCARD_MESSAGE */ 402 489 { 403 ipcMessage *nextToCheck = lastChecked->mNext; 404 405 // discard from pending queue 406 if (beforeLastChecked) 407 td->pendingQ.DeleteAfter(beforeLastChecked); 408 else 409 td->pendingQ.DeleteFirst(); 410 411 lastChecked = nextToCheck; 412 490 RTListNodeRemove(&pIt->NdMsg); 491 IPC_MsgFree(pIt); 413 492 continue; 414 493 } 415 494 } 416 495 } 417 418 beforeLastChecked = lastChecked; 419 lastChecked = lastChecked->mNext; 420 } 421 422 if (*aMsg) 496 } 497 498 if (*ppMsg) 423 499 { 424 500 rv = NS_OK; … … 434 510 if (aliveRV != IPC_WAIT_NEXT_MESSAGE) 435 511 { 436 * aMsg = NULL;512 *ppMsg = NULL; 437 513 break; 438 514 } … … 452 528 453 529 Log(("woke up from sleep [pendingQempty=%d connected=%d shutdown=%d isIPCMTarget=%d]\n", 454 td->pendingQ.IsEmpty(), gClientState->connected,530 RTListIsEmpty(&td->LstPendingMsgs), gClientState->connected, 455 531 gClientState->shutdown, isIPCMTarget)); 456 532 } … … 592 668 nsAutoMonitor mon(td->monitor); 593 669 if (td->observerDisabled > 0 && --td->observerDisabled == 0) 594 if (! td->pendingQ.IsEmpty())670 if (!RTListIsEmpty(&td->LstPendingMsgs)) 595 671 CallProcessPendingQ(aTarget, td); 596 672 } … … 600 676 601 677 // converts IPCM_ERROR_* status codes to NS_ERROR_* status codes 602 static nsresult nsresult_from_ipcm_result( PRInt32status)678 static nsresult nsresult_from_ipcm_result(int32_t status) 603 679 { 604 680 nsresult rv = NS_ERROR_FAILURE; … … 622 698 // selects the next IPCM message with matching request index 623 699 static nsresult 624 WaitIPCMResponseSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)700 WaitIPCMResponseSelector(void *arg, ipcTargetData *td, PCIPCMSG pMsg) 625 701 { 626 702 #ifdef VBOX 627 if (! msg)703 if (!pMsg) 628 704 return IPC_WAIT_NEXT_MESSAGE; 629 705 #endif /* VBOX */ 630 706 PRUint32 requestIndex = *(PRUint32 *) arg; 631 return IPCM_GetRequestIndex( msg) == requestIndex ? NS_OK : IPC_WAIT_NEXT_MESSAGE;707 return IPCM_GetRequestIndex(pMsg) == requestIndex ? NS_OK : IPC_WAIT_NEXT_MESSAGE; 632 708 } 633 709 … … 637 713 // status code is mapped to a nsresult and returned by this function. 638 714 static nsresult 639 WaitIPCMResponse(PRUint32 requestIndex, ipcMessage **responseMsg = nsnull)640 { 641 ipcMessage *msg;642 643 nsresult rv = WaitTarget(IPCM_TARGET, IPC_REQUEST_TIMEOUT, & msg,715 WaitIPCMResponse(PRUint32 requestIndex, PIPCMSG *ppMsgResponse = NULL) 716 { 717 PIPCMSG pMsg; 718 719 nsresult rv = WaitTarget(IPCM_TARGET, IPC_REQUEST_TIMEOUT, &pMsg, 644 720 WaitIPCMResponseSelector, &requestIndex); 645 721 if (NS_FAILED(rv)) 646 722 return rv; 647 723 648 if (IPCM_GetType( msg) == IPCM_MSG_ACK_RESULT)649 { 650 ipcMessageCast<ipcmMessageResult> result(msg);651 if ( result->Status()< 0)652 rv = nsresult_from_ipcm_result( result->Status());724 if (IPCM_GetType(pMsg) == IPCM_MSG_ACK_RESULT) 725 { 726 PCIPCMMSGRESULT pIpcmRes = (PCIPCMMSGRESULT)IPCMsgGetPayload(pMsg); 727 if (pIpcmRes->i32Status < 0) 728 rv = nsresult_from_ipcm_result(pIpcmRes->i32Status); 653 729 else 654 730 rv = NS_OK; 655 731 } 656 732 657 if ( responseMsg)658 * responseMsg = msg;733 if (ppMsgResponse) 734 *ppMsgResponse = pMsg; 659 735 else 660 delete msg;736 IPC_MsgFree(pMsg); 661 737 662 738 return rv; … … 665 741 // make an IPCM request and wait for a response. 666 742 static nsresult 667 MakeIPCMRequest(ipcMessage *msg, ipcMessage **responseMsg = nsnull) 668 { 669 if (!msg) 670 return NS_ERROR_OUT_OF_MEMORY; 671 672 PRUint32 requestIndex = IPCM_GetRequestIndex(msg); 673 674 // suppress 'ProcessPendingQ' for IPCM messages until we receive the 675 // response to this IPCM request. if we did not do this then there 676 // would be a race condition leading to the possible removal of our 677 // response from the pendingQ between sending the request and waiting 678 // for the response. 679 DisableMessageObserver(IPCM_TARGET); 680 681 nsresult rv = IPC_SendMsg(msg); 682 if (NS_SUCCEEDED(rv)) 683 rv = WaitIPCMResponse(requestIndex, responseMsg); 684 685 EnableMessageObserver(IPCM_TARGET); 686 return rv; 687 } 688 689 /* ------------------------------------------------------------------------- */ 690 691 static void 692 RemoveTarget(const nsID &aTarget, PRBool aNotifyDaemon) 693 { 694 DelTarget(aTarget); 695 696 if (aNotifyDaemon) 697 { 698 nsresult rv = MakeIPCMRequest(new ipcmMessageClientDelTarget(aTarget)); 699 if (NS_FAILED(rv)) 700 Log(("failed to delete target: rv=%x\n", rv)); 701 } 743 MakeIPCMRequest(PIPCMSG pMsg, PIPCMSG *ppMsgResponse = NULL) 744 { 745 AssertPtrReturn(pMsg, NS_ERROR_OUT_OF_MEMORY); 746 747 uint32_t requestIndex = IPCM_GetRequestIndex(pMsg); 748 749 // suppress 'ProcessPendingQ' for IPCM messages until we receive the 750 // response to this IPCM request. if we did not do this then there 751 // would be a race condition leading to the possible removal of our 752 // response from the pendingQ between sending the request and waiting 753 // for the response. 754 DisableMessageObserver(IPCM_TARGET); 755 756 nsresult rv = IPC_SendMsg(pMsg); 757 if (NS_SUCCEEDED(rv)) 758 rv = WaitIPCMResponse(requestIndex, ppMsgResponse); 759 760 EnableMessageObserver(IPCM_TARGET); 761 return rv; 762 } 763 764 /* ------------------------------------------------------------------------- */ 765 766 static void RemoveTarget(const nsID &aTarget, PRBool aNotifyDaemon) 767 { 768 DelTarget(aTarget); 769 770 if (aNotifyDaemon) 771 { 772 IPCMMSGSTACK IpcmMsg; 773 IPCMSG IpcMsg; 774 775 IPCMMsgDelTargetInit(&IpcmMsg.Ipcm.AddDelTarget, aTarget); 776 IPCMsgInitStack(&IpcMsg, IPCM_TARGET, &IpcmMsg, sizeof(IpcmMsg.Ipcm.AddDelTarget)); 777 nsresult rv = MakeIPCMRequest(&IpcMsg); 778 if (NS_FAILED(rv)) 779 Log(("failed to delete target: rv=%x\n", rv)); 780 } 702 781 } 703 782 … … 709 788 ipcTargetData **aResult) 710 789 { 711 nsresult rv; 712 713 nsRefPtr<ipcTargetData> td( ipcTargetData::Create() ); 714 if (!td) 715 return NS_ERROR_OUT_OF_MEMORY; 716 td->SetObserver(aObserver, aOnCurrentThread); 717 718 if (!PutTarget(aTarget, td)) 719 return NS_ERROR_OUT_OF_MEMORY; 720 721 if (aNotifyDaemon) 722 { 723 rv = MakeIPCMRequest(new ipcmMessageClientAddTarget(aTarget)); 724 if (NS_FAILED(rv)) 725 { 726 Log(("failed to add target: rv=%x\n", rv)); 727 RemoveTarget(aTarget, PR_FALSE); 728 return rv; 729 } 730 } 731 732 if (aResult) 733 NS_ADDREF(*aResult = td); 734 return NS_OK; 790 nsresult rv; 791 792 nsRefPtr<ipcTargetData> td( ipcTargetData::Create() ); 793 if (!td) 794 return NS_ERROR_OUT_OF_MEMORY; 795 td->SetObserver(aObserver, aOnCurrentThread); 796 797 if (!PutTarget(aTarget, td)) 798 return NS_ERROR_OUT_OF_MEMORY; 799 800 if (aNotifyDaemon) 801 { 802 IPCMMSGSTACK IpcmMsg; 803 IPCMSG IpcMsg; 804 805 IPCMMsgAddTargetInit(&IpcmMsg.Ipcm.AddDelTarget, aTarget); 806 IPCMsgInitStack(&IpcMsg, IPCM_TARGET, &IpcmMsg, sizeof(IpcmMsg.Ipcm.AddDelTarget)); 807 rv = MakeIPCMRequest(&IpcMsg); 808 if (NS_FAILED(rv)) 809 { 810 Log(("failed to add target: rv=%x\n", rv)); 811 RemoveTarget(aTarget, PR_FALSE); 812 return rv; 813 } 814 } 815 816 if (aResult) 817 NS_ADDREF(*aResult = td); 818 return NS_OK; 735 819 } 736 820 … … 740 824 TryConnect() 741 825 { 742 nsCAutoString dpath; 743 nsresult rv = GetDaemonPath(dpath); 744 if (NS_FAILED(rv)) 826 nsCAutoString dpath; 827 nsresult rv = GetDaemonPath(dpath); 828 if (NS_FAILED(rv)) 829 return rv; 830 831 rv = IPC_Connect(dpath.get()); 832 if (NS_FAILED(rv)) 833 return rv; 834 835 gClientState->connected = PR_TRUE; 836 837 rv = DefineTarget(IPCM_TARGET, nsnull, PR_FALSE, PR_FALSE, nsnull); 838 if (NS_FAILED(rv)) 839 return rv; 840 841 PIPCMSG pMsg = NULL; 842 843 // send CLIENT_HELLO and wait for CLIENT_ID response... 844 IPCMMSGSTACK IpcmMsg; 845 IPCMSG IpcMsg; 846 847 IPCMMsgClientHelloInit(&IpcmMsg.Ipcm.ClientHello); 848 IPCMsgInitStack(&IpcMsg, IPCM_TARGET, &IpcmMsg, sizeof(IpcmMsg.Ipcm.ClientHello)); 849 rv = MakeIPCMRequest(&IpcMsg, &pMsg); 850 if (NS_FAILED(rv)) 851 { 852 #ifdef VBOX /* MakeIPCMRequest may return a failure (e.g. NS_ERROR_CALL_FAILED) and a response msg. */ 853 if (pMsg) 854 IPC_MsgFree(pMsg); 855 #endif 856 return rv; 857 } 858 859 if (IPCM_GetType(pMsg) == IPCM_MSG_ACK_CLIENT_ID) 860 { 861 PCIPCMMSGCLIENTID pIpcmClientId = (PCIPCMMSGCLIENTID)IPCMsgGetPayload(pMsg); 862 gClientState->selfID = pIpcmClientId->u32ClientId; 863 } 864 else 865 { 866 Log(("unexpected response from CLIENT_HELLO message: type=%x!\n", IPCM_GetType(pMsg))); 867 rv = NS_ERROR_UNEXPECTED; 868 } 869 870 IPC_MsgFree(pMsg); 745 871 return rv; 746 747 rv = IPC_Connect(dpath.get());748 if (NS_FAILED(rv))749 return rv;750 751 gClientState->connected = PR_TRUE;752 753 rv = DefineTarget(IPCM_TARGET, nsnull, PR_FALSE, PR_FALSE, nsnull);754 if (NS_FAILED(rv))755 return rv;756 757 ipcMessage *msg = NULL;758 759 // send CLIENT_HELLO and wait for CLIENT_ID response...760 rv = MakeIPCMRequest(new ipcmMessageClientHello(), &msg);761 if (NS_FAILED(rv))762 {763 #ifdef VBOX /* MakeIPCMRequest may return a failure (e.g. NS_ERROR_CALL_FAILED) and a response msg. */764 if (msg)765 delete msg;766 #endif767 return rv;768 }769 770 if (IPCM_GetType(msg) == IPCM_MSG_ACK_CLIENT_ID)771 gClientState->selfID = ipcMessageCast<ipcmMessageClientID>(msg)->ClientID();772 else773 {774 Log(("unexpected response from CLIENT_HELLO message: type=%x!\n",775 IPCM_GetType(msg)));776 rv = NS_ERROR_UNEXPECTED;777 }778 779 delete msg;780 return rv;781 872 } 782 873 … … 925 1016 PRUint32 aDataLen) 926 1017 { 927 NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED); 928 929 // do not permit sending IPCM messages 930 if (aTarget.Equals(IPCM_TARGET)) 931 return NS_ERROR_INVALID_ARG; 932 933 nsresult rv; 934 if (aReceiverID == 0) 935 { 936 ipcMessage *msg = new ipcMessage(aTarget, (const char *) aData, aDataLen); 937 if (!msg) 938 return NS_ERROR_OUT_OF_MEMORY; 939 940 rv = IPC_SendMsg(msg); 941 } 942 else 943 rv = MakeIPCMRequest(new ipcmMessageForward(IPCM_MSG_REQ_FORWARD, 944 aReceiverID, 945 aTarget, 946 (const char *) aData, 947 aDataLen)); 948 949 return rv; 1018 NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED); 1019 1020 // do not permit sending IPCM messages 1021 if (aTarget.Equals(IPCM_TARGET)) 1022 return NS_ERROR_INVALID_ARG; 1023 1024 nsresult rv; 1025 if (aReceiverID == 0) 1026 { 1027 RTSGSEG Seg = { (void *)aData, aDataLen }; 1028 PIPCMSG pMsg = IPC_MsgNewSg(aTarget, aDataLen, &Seg, 1 /*cSegs*/); 1029 if (!pMsg) 1030 return NS_ERROR_OUT_OF_MEMORY; 1031 1032 rv = IPC_SendMsg(pMsg); 1033 } 1034 else 1035 { 1036 IPCMSGHDR InnerMsgHdr; 1037 IPCMMSGFORWARD IpcmFwd; 1038 RTSGSEG aSegs[3]; 1039 1040 /* Construct the forwarded message. */ 1041 IpcmFwd.Hdr.u32Type = IPCM_MSG_REQ_FORWARD; 1042 IpcmFwd.Hdr.u32RequestIndex = IPCM_NewRequestIndex(); 1043 IpcmFwd.u32ClientId = aReceiverID; 1044 1045 aSegs[0].pvSeg = &IpcmFwd; 1046 aSegs[0].cbSeg = sizeof(IpcmFwd); 1047 aSegs[1].pvSeg = IPCMsgHdrInit(&InnerMsgHdr, aTarget, aDataLen); 1048 aSegs[1].cbSeg = sizeof(InnerMsgHdr); 1049 aSegs[2].pvSeg = (void *)aData; 1050 aSegs[2].cbSeg = aDataLen; 1051 1052 PIPCMSG pMsg = IPC_MsgNewSg(IPCM_TARGET, aDataLen + sizeof(IpcmFwd) + sizeof(InnerMsgHdr), 1053 &aSegs[0], RT_ELEMENTS(aSegs)); 1054 rv = MakeIPCMRequest(pMsg); 1055 } 1056 1057 return rv; 950 1058 } 951 1059 … … 957 1065 }; 958 1066 959 static nsresult WaitMessageSelector(void *arg, ipcTargetData *td, const ipcMessage *msg)1067 static nsresult WaitMessageSelector(void *arg, ipcTargetData *td, PCIPCMSG pMsg) 960 1068 { 961 1069 WaitMessageSelectorData *data = (WaitMessageSelectorData *) arg; 962 1070 #ifdef VBOX 963 if (! msg)1071 if (!pMsg) 964 1072 { 965 1073 /* Special NULL message which asks to check whether the client is … … 981 1089 // sender we're waiting a message from has died. 982 1090 983 if ( msg->Target().Equals(IPCM_TARGET))984 { 985 switch (IPCM_GetType( msg))1091 if (IPCMsgGetTarget(pMsg)->Equals(IPCM_TARGET)) 1092 { 1093 switch (IPCM_GetType(pMsg)) 986 1094 { 987 1095 case IPCM_MSG_PSH_CLIENT_STATE: 988 1096 { 989 ipcMessageCast<ipcmMessageClientState> status(msg);1097 PCIPCMMSGCLIENTSTATE pClientState = (PCIPCMMSGCLIENTSTATE)IPCMsgGetPayload(pMsg); 990 1098 if ((data->senderID == IPC_SENDER_ANY || 991 status->ClientID()== data->senderID) &&992 status->ClientState()== IPCM_CLIENT_STATE_DOWN)1099 pClientState->u32ClientId == data->senderID) && 1100 pClientState->u32ClientStatus == IPCM_CLIENT_STATE_DOWN) 993 1101 { 994 1102 Log(("sender (%d) we're waiting a message from (%d) has died\n", 995 status->ClientID(), data->senderID));1103 pClientState->u32ClientId, data->senderID)); 996 1104 997 1105 if (data->senderID != IPC_SENDER_ANY) … … 1014 1122 NS_ASSERTION(obs, "must at least have a default observer"); 1015 1123 1016 nsresult rv = obs->OnMessageAvailable( status->ClientID(), nsID(), 0, 0);1124 nsresult rv = obs->OnMessageAvailable(pClientState->u32ClientId, nsID(), 0, 0); 1017 1125 if (rv != IPC_WAIT_NEXT_MESSAGE) 1018 1126 data->senderDead = PR_TRUE; … … 1023 1131 #ifdef VBOX 1024 1132 else if ((data->senderID == IPC_SENDER_ANY || 1025 status->ClientID() == data->senderID) &&1026 status->ClientState()== IPCM_CLIENT_STATE_UP)1133 pClientState->u32ClientId) && 1134 pClientState->u32ClientStatus == IPCM_CLIENT_STATE_UP) 1027 1135 { 1028 1136 Log(("sender (%d) we're waiting a message from (%d) has come up\n", 1029 status->ClientID(), data->senderID));1137 pClientState->u32ClientId, data->senderID)); 1030 1138 if (data->senderID == IPC_SENDER_ANY) 1031 1139 { … … 1038 1146 NS_ASSERTION(obs, "must at least have a default observer"); 1039 1147 1040 nsresult rv = obs->OnMessageAvailable( status->ClientID(), nsID(), 0, 1);1148 nsresult rv = obs->OnMessageAvailable(pClientState->u32ClientId, nsID(), 0, 1); 1041 1149 /* VBoxSVC/VBoxXPCOMIPCD auto-start can cause that a client up 1042 1150 * message arrives while we're already waiting for a response … … 1062 1170 1063 1171 if (data->senderID == IPC_SENDER_ANY || 1064 msg->mMetaData== data->senderID)1172 pMsg->upUser == data->senderID) 1065 1173 { 1066 1174 ipcIMessageObserver *obs = data->observer; … … 1069 1177 NS_ASSERTION(obs, "must at least have a default observer"); 1070 1178 1071 rv = obs->OnMessageAvailable( msg->mMetaData,1072 msg->Target(),1073 (const PRUint8 *) msg->Data(),1074 msg->DataLen());1179 rv = obs->OnMessageAvailable(pMsg->upUser, 1180 *IPCMsgGetTarget(pMsg), 1181 (const PRUint8 *)IPCMsgGetPayload(pMsg), 1182 IPCMsgGetPayloadSize(pMsg)); 1075 1183 } 1076 1184 … … 1095 1203 WaitMessageSelectorData data = { aSenderID, aObserver, PR_FALSE }; 1096 1204 1097 ipcMessage *msg;1098 nsresult rv = WaitTarget(aTarget, aTimeout, & msg, WaitMessageSelector, &data);1205 PIPCMSG pMsg; 1206 nsresult rv = WaitTarget(aTarget, aTimeout, &pMsg, WaitMessageSelector, &data); 1099 1207 if (NS_FAILED(rv)) 1100 1208 return rv; … … 1106 1214 if (aObserver && aConsumer) 1107 1215 { 1108 aConsumer->OnMessageAvailable( msg->mMetaData,1109 msg->Target(),1110 (const PRUint8 *) msg->Data(),1111 msg->DataLen());1112 } 1113 1114 delete msg;1216 aConsumer->OnMessageAvailable(pMsg->upUser, 1217 *IPCMsgGetTarget(pMsg), 1218 (const PRUint8 *)IPCMsgGetPayload(pMsg), 1219 IPCMsgGetPayloadSize(pMsg)); 1220 } 1221 1222 IPC_MsgFree(pMsg); 1115 1223 1116 1224 // if the requested sender has died while waiting, return an error … … 1135 1243 IPC_AddName(const char *aName) 1136 1244 { 1137 NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED); 1138 1139 return MakeIPCMRequest(new ipcmMessageClientAddName(aName)); 1245 NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED); 1246 1247 size_t cbStr = strlen(aName) + 1; /* Includes terminator. */ 1248 const IPCMMSGHDR Hdr = { IPCM_MSG_REQ_CLIENT_ADD_NAME, IPCM_NewRequestIndex() }; 1249 RTSGSEG aSegs[2]; 1250 1251 aSegs[0].pvSeg = (void *)&Hdr; 1252 aSegs[0].cbSeg = sizeof(Hdr); 1253 1254 aSegs[1].pvSeg = (void *)aName; 1255 aSegs[1].cbSeg = cbStr; 1256 1257 PIPCMSG pMsg = IPC_MsgNewSg(IPCM_TARGET, cbStr + sizeof(Hdr), 1258 &aSegs[0], RT_ELEMENTS(aSegs)); 1259 return MakeIPCMRequest(pMsg); 1140 1260 } 1141 1261 … … 1143 1263 IPC_RemoveName(const char *aName) 1144 1264 { 1145 NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED); 1146 1147 return MakeIPCMRequest(new ipcmMessageClientDelName(aName)); 1265 NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED); 1266 1267 size_t cbStr = strlen(aName) + 1; /* Includes terminator. */ 1268 const IPCMMSGHDR Hdr = { IPCM_MSG_REQ_CLIENT_DEL_NAME, IPCM_NewRequestIndex() }; 1269 RTSGSEG aSegs[2]; 1270 1271 aSegs[0].pvSeg = (void *)&Hdr; 1272 aSegs[0].cbSeg = sizeof(Hdr); 1273 1274 aSegs[1].pvSeg = (void *)aName; 1275 aSegs[1].cbSeg = cbStr; 1276 1277 PIPCMSG pMsg = IPC_MsgNewSg(IPCM_TARGET, cbStr + sizeof(Hdr), 1278 &aSegs[0], RT_ELEMENTS(aSegs)); 1279 return MakeIPCMRequest(pMsg); 1148 1280 } 1149 1281 … … 1179 1311 IPC_ResolveClientName(const char *aName, PRUint32 *aClientID) 1180 1312 { 1181 NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED); 1182 1183 ipcMessage *msg = NULL; 1184 1185 nsresult rv = MakeIPCMRequest(new ipcmMessageQueryClientByName(aName), &msg); 1186 if (NS_FAILED(rv)) 1187 { 1188 #ifdef VBOX /* MakeIPCMRequest may return a failure (e.g. NS_ERROR_CALL_FAILED) and a response msg. */ 1189 if (msg) 1190 delete msg; 1191 #endif 1313 NS_ENSURE_TRUE(gClientState, NS_ERROR_NOT_INITIALIZED); 1314 1315 size_t cbStr = strlen(aName) + 1; /* Includes terminator. */ 1316 const IPCMMSGHDR Hdr = { IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME, IPCM_NewRequestIndex() }; 1317 RTSGSEG aSegs[2]; 1318 1319 aSegs[0].pvSeg = (void *)&Hdr; 1320 aSegs[0].cbSeg = sizeof(Hdr); 1321 1322 aSegs[1].pvSeg = (void *)aName; 1323 aSegs[1].cbSeg = cbStr; 1324 1325 PIPCMSG pMsg = IPC_MsgNewSg(IPCM_TARGET, cbStr + sizeof(Hdr), 1326 &aSegs[0], RT_ELEMENTS(aSegs)); 1327 1328 PIPCMSG pMsgResp = NULL; 1329 nsresult rv = MakeIPCMRequest(pMsg, &pMsgResp); 1330 if (NS_FAILED(rv)) 1331 { 1332 /* MakeIPCMRequest may return a failure (e.g. NS_ERROR_CALL_FAILED) and a response msg. */ 1333 if (pMsgResp) 1334 IPC_MsgFree(pMsgResp); 1335 1336 return rv; 1337 } 1338 1339 if (IPCM_GetType(pMsgResp) == IPCM_MSG_ACK_CLIENT_ID) 1340 { 1341 PCIPCMMSGCLIENTID pClientId = (PCIPCMMSGCLIENTID)IPCMsgGetPayload(pMsgResp); 1342 *aClientID = pClientId->u32ClientId; 1343 } 1344 else 1345 { 1346 Log(("unexpected IPCM response: type=%x\n", IPCM_GetType(pMsg))); 1347 rv = NS_ERROR_UNEXPECTED; 1348 } 1349 1350 IPC_MsgFree(pMsgResp); 1192 1351 return rv; 1193 } 1194 1195 if (IPCM_GetType(msg) == IPCM_MSG_ACK_CLIENT_ID) 1196 *aClientID = ipcMessageCast<ipcmMessageClientID>(msg)->ClientID(); 1197 else 1198 { 1199 Log(("unexpected IPCM response: type=%x\n", IPCM_GetType(msg))); 1200 rv = NS_ERROR_UNEXPECTED; 1201 } 1202 1203 delete msg; 1204 return rv; 1205 } 1206 1207 /* ------------------------------------------------------------------------- */ 1208 1209 nsresult 1210 IPC_ClientExists(PRUint32 aClientID, PRBool *aResult) 1211 { 1212 // this is a bit of a hack. we forward a PING to the specified client. 1213 // the assumption is that the forwarding will only succeed if the client 1214 // exists, so we wait for the RESULT message corresponding to the FORWARD 1215 // request. if that gives a successful status, then we know that the 1216 // client exists. 1217 1218 ipcmMessagePing ping; 1219 1220 return MakeIPCMRequest(new ipcmMessageForward(IPCM_MSG_REQ_FORWARD, 1221 aClientID, 1222 IPCM_TARGET, 1223 ping.Data(), 1224 ping.DataLen())); 1225 } 1352 } 1353 1226 1354 1227 1355 /* ------------------------------------------------------------------------- */ … … 1246 1374 "--inherit-startup-pipe", 1247 1375 &szPipeInheritFd[0], NULL }; 1248 char c;1249 1376 1250 1377 ssize_t cch = RTStrFormatU32(&szPipeInheritFd[0], sizeof(szPipeInheritFd), 1251 1378 (uint32_t)RTPipeToNative(hPipeWr), 10 /*uiBase*/, 1252 1379 0 /*cchWidth*/, 0 /*cchPrecision*/, 0 /*fFlags*/); 1253 Assert(cch > 0); 1380 Assert(cch > 0); RT_NOREF(cch); 1254 1381 1255 1382 RTHANDLE hStdNil; … … 1315 1442 1316 1443 static void 1317 PlaceOnPendingQ(const nsID &target, ipcTargetData *td, ipcMessage *msg)1444 PlaceOnPendingQ(const nsID &target, ipcTargetData *td, PIPCMSG pMsg) 1318 1445 { 1319 1446 nsAutoMonitor mon(td->monitor); … … 1321 1448 // we only want to dispatch a 'ProcessPendingQ' event if we have not 1322 1449 // already done so. 1323 PRBool dispatchEvent = td->pendingQ.IsEmpty();1450 PRBool dispatchEvent = RTListIsEmpty(&td->LstPendingMsgs); 1324 1451 1325 1452 // put this message on our pending queue 1326 td->pendingQ.Append(msg);1453 RTListAppend(&td->LstPendingMsgs, &pMsg->NdMsg); 1327 1454 1328 1455 #ifdef LOG_ENABLED … … 1350 1477 { 1351 1478 // place a message clone to a target's event queue 1352 ipcMessage *msg = (ipcMessage *)userArg;1353 PlaceOnPendingQ(aKey, aData, msg->Clone());1479 PCIPCMSG pMsg = (PCIPCMSG)userArg; 1480 PlaceOnPendingQ(aKey, aData, IPC_MsgClone(pMsg)); 1354 1481 } 1355 1482 … … 1360 1487 1361 1488 // called on a background thread 1362 void 1363 IPC_OnMessageAvailable(ipcMessage *msg) 1364 { 1489 DECLHIDDEN(void) IPC_OnMessageAvailable(PCIPCMSG pMsg) 1490 { 1491 const nsID target = *IPCMsgGetTarget(pMsg); 1492 1365 1493 #ifdef LOG_ENABLED 1366 1494 { 1367 char *targetStr = msg->Target().ToString();1495 char *targetStr = target.ToString(); 1368 1496 Log(("got message for target: %s\n", targetStr)); 1369 1497 nsMemory::Free(targetStr); … … 1373 1501 #endif 1374 1502 1375 if (msg->Target().Equals(IPCM_TARGET)) 1376 { 1377 switch (IPCM_GetType(msg)) 1378 { 1379 // if this is a forwarded message, then post the inner message instead. 1503 if (target.Equals(IPCM_TARGET)) 1504 { 1505 switch (IPCM_GetType(pMsg)) 1506 { 1380 1507 case IPCM_MSG_PSH_FORWARD: 1381 1508 { 1382 ipcMessageCast<ipcmMessageForward> fwd(msg); 1383 ipcMessage *innerMsg = new ipcMessage(fwd->InnerTarget(), 1384 fwd->InnerData(), 1385 fwd->InnerDataLen()); 1386 // store the sender's client id in the meta-data field of the message. 1387 innerMsg->mMetaData = fwd->ClientID(); 1388 1389 delete msg; 1390 1391 // recurse so we can handle forwarded IPCM messages 1392 IPC_OnMessageAvailable(innerMsg); 1509 PCIPCMMSGFORWARD pFwd = (PCIPCMMSGFORWARD)IPCMsgGetPayload(pMsg); 1510 1511 /** @todo De-uglify this. */ 1512 /* Forward the inner message. */ 1513 IPCMSG InnerMsg; RT_ZERO(InnerMsg); 1514 InnerMsg.pMsgHdr = (PIPCMSGHDR)(pFwd + 1); 1515 InnerMsg.cbBuf = InnerMsg.pMsgHdr->cbMsg; 1516 InnerMsg.pbBuf = (uint8_t *)InnerMsg.pMsgHdr; 1517 InnerMsg.upUser = pFwd->u32ClientId; 1518 1519 /* Recurse to forward the inner message (it will get cloned). */ 1520 IPC_OnMessageAvailable(&InnerMsg); 1393 1521 return; 1394 1522 } 1395 1523 case IPCM_MSG_PSH_CLIENT_STATE: 1396 1524 { 1397 ipcMessageCast<ipcmMessageClientState> status(msg);1398 PostEventToMainThread(new ipcEvent_ClientState( status->ClientID(),1399 status->ClientState()));1525 PCIPCMMSGCLIENTSTATE pClientState = (PCIPCMMSGCLIENTSTATE)IPCMsgGetPayload(pMsg); 1526 PostEventToMainThread(new ipcEvent_ClientState(pClientState->u32ClientId, 1527 pClientState->u32ClientStatus)); 1400 1528 1401 1529 // go through the target map, and place this message to every target's … … 1404 1532 // the peer client death, when appropriate. 1405 1533 RTCritSectRwEnterShared(&gClientState->critSect); 1406 gClientState->targetMap.EnumerateRead(EnumerateTargetMapAndPlaceMsg, msg);1534 gClientState->targetMap.EnumerateRead(EnumerateTargetMapAndPlaceMsg, (void *)pMsg); 1407 1535 RTCritSectRwLeaveShared(&gClientState->critSect); 1408 1409 delete msg;1410 1536 return; 1411 1537 } … … 1414 1540 1415 1541 nsRefPtr<ipcTargetData> td; 1416 if (GetTarget(msg->Target(), getter_AddRefs(td))) 1417 { 1418 // make copy of target since |msg| may end up pointing to free'd memory 1419 // once we notify the monitor inside PlaceOnPendingQ(). 1420 const nsID target = msg->Target(); 1421 1422 PlaceOnPendingQ(target, td, msg); 1542 if (GetTarget(target, getter_AddRefs(td))) 1543 { 1544 PIPCMSG pClone = IPC_MsgClone(pMsg); 1545 PlaceOnPendingQ(target, td, pClone); 1423 1546 } 1424 1547 else 1425 {1426 1548 NS_WARNING("message target is undefined"); 1427 #ifdef VBOX 1428 delete msg; 1429 #endif 1430 } 1431 } 1549 } -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcCommandModule.cpp
r103378 r103472 51 51 52 52 53 DECLINLINE(uint32_t) IPCM_GetType(PCIPCMSG pMsg)54 {55 return ((const ipcmMessageHeader *)IPCMsgGetPayload(pMsg))->mType;56 }57 58 59 DECLINLINE(uint32_t) IPCM_GetRequestIndex(PCIPCMSG pMsg)60 {61 return ((const ipcmMessageHeader *)IPCMsgGetPayload(pMsg))->mRequestIndex;62 }63 64 53 // 65 54 // message handlers … … 70 59 Log(("got PING\n")); 71 60 72 const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), IPCM_OK };73 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));61 const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg) }, IPCM_OK }; 62 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes)); 74 63 } 75 64 … … 78 67 Log(("got CLIENT_HELLO\n")); 79 68 80 const uint32_t aResp[3] = { IPCM_MSG_ACK_CLIENT_ID, IPCM_GetRequestIndex(pMsg), ipcdClientGetId(pIpcClient) };81 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));69 const IPCMMSGCLIENTID IcmpRes = { { IPCM_MSG_ACK_CLIENT_ID, IPCM_GetRequestIndex(pMsg) }, ipcdClientGetId(pIpcClient) }; 70 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcmpRes, sizeof(IcmpRes)); 82 71 83 72 // … … 113 102 status = IPCM_ERROR_INVALID_ARG; 114 103 115 const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, requestIndex, (uint32_t)status };116 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));104 const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, status }; 105 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes)); 117 106 } 118 107 … … 136 125 status = IPCM_ERROR_INVALID_ARG; 137 126 138 const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), (uint32_t)status };139 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));127 const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, status }; 128 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes)); 140 129 } 141 130 … … 156 145 ipcdClientAddTarget(pIpcClient, pidTarget); 157 146 158 const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), (uint32_t)status };159 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));147 const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, status }; 148 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes)); 160 149 } 161 150 … … 174 163 } 175 164 176 const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), (uint32_t)status };177 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));165 const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, status }; 166 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes)); 178 167 } 179 168 … … 189 178 { 190 179 Log((" client exists w/ ID = %u\n", ipcdClientGetId(pIpcClientResult))); 191 const uint32_t aResp[3] = { IPCM_MSG_ACK_CLIENT_ID, requestIndex, ipcdClientGetId(pIpcClientResult) };192 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));180 const IPCMMSGCLIENTID IcmpRes = { { IPCM_MSG_ACK_CLIENT_ID, requestIndex }, ipcdClientGetId(pIpcClientResult) }; 181 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcmpRes, sizeof(IcmpRes)); 193 182 } 194 183 else 195 184 { 196 185 Log((" client does not exist\n")); 197 const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, requestIndex, (uint32_t)IPCM_ERROR_NO_CLIENT };198 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));186 const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, IPCM_ERROR_NO_CLIENT }; 187 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes)); 199 188 } 200 189 } … … 203 192 { 204 193 Log(("got FORWARD\n")); 194 195 PRUint32 requestIndex = IPCM_GetRequestIndex(pMsg); 205 196 206 197 uint32_t idClient = *(uint32_t *)((uint8_t *)IPCMsgGetPayload(pMsg) + 2 * sizeof(uint32_t)); … … 209 200 { 210 201 Log((" destination client not found!\n")); 211 const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), (uint32_t)IPCM_ERROR_NO_CLIENT };212 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));202 const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, IPCM_ERROR_NO_CLIENT }; 203 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes)); 213 204 return; 214 205 } 215 206 // inform client that its message will be forwarded 216 const uint32_t aResp[3] = { IPCM_MSG_ACK_RESULT, IPCM_GetRequestIndex(pMsg), IPCM_OK };217 IPC_SendMsg(pIpcClient, IPCM_TARGET, & aResp[0], sizeof(aResp));207 const IPCMMSGRESULT IcpmRes = { { IPCM_MSG_ACK_RESULT, requestIndex }, IPCM_OK }; 208 IPC_SendMsg(pIpcClient, IPCM_TARGET, &IcpmRes, sizeof(IcpmRes)); 218 209 219 210 uint32_t aIpcmFwdHdr[3] = { IPCM_MSG_PSH_FORWARD, IPCM_NewRequestIndex(), ipcdClientGetId(pIpcClient) }; -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcd.cpp
r103378 r103472 116 116 const char lockName[] = "lock"; 117 117 118 int dirLen = strlen(baseDir);119 int len = dirLen // baseDir120 + 1 // "/"121 + sizeof(lockName); // "lock"118 size_t dirLen = strlen(baseDir); 119 size_t len = dirLen // baseDir 120 + 1 // "/" 121 + sizeof(lockName); // "lock" 122 122 123 123 // … … 410 410 // remember if client is expecting SYNC_REPLY. we'll add that flag to the 411 411 // next message sent to the client. 412 if (IPCMsgIsFlagSet(pMsg, IPC_MSG_ FLAG_SYNC_QUERY))412 if (IPCMsgIsFlagSet(pMsg, IPC_MSG_HDR_FLAG_SYNC_QUERY)) 413 413 { 414 414 Assert(!ipcdClientGetExpectsSyncReply(pIpcClient)); … … 432 432 // add SYNC_REPLY flag to message if client is expecting... 433 433 if (ipcdClientGetExpectsSyncReply(pIpcClient)) { 434 pMsg->pMsgHdr->u16Flags |= IPC_MSG_ FLAG_SYNC_REPLY;434 pMsg->pMsgHdr->u16Flags |= IPC_MSG_HDR_FLAG_SYNC_REPLY; 435 435 ipcdClientSetExpectsSyncReply(pIpcClient, false); 436 436 } … … 591 591 // we terminate 592 592 if (status != ELockFileOwner) 593 printf("Cannot create a lock file for '%s'.\n"594 "Check permissions.\n", addr.sun_path);593 RTMsgError("Cannot create a lock file for '%s'.\n" 594 "Check permissions.\n", addr.sun_path); 595 595 return VERR_INVALID_PARAMETER; 596 596 } -
trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcConfig.cpp
r102340 r103472 53 53 { 54 54 const char *logName; 55 int len;56 55 57 56 char *pszDst = buf; -
trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcMessageNew.h
r103378 r103472 121 121 /** Flag whether the message is complete and the buffer is therefore readonly right now. */ 122 122 bool fReadonly; 123 /** Flag whether the message is living on the stack and shouldn't be freed. */ 124 bool fStack; 125 /** Some metadata which is up to the user to use. */ 126 uintptr_t upUser; 123 127 } IPCMSG; 124 128 /** Pointer to an IPC message. */ … … 128 132 129 133 134 DECLINLINE(PIPCMSGHDR) IPCMsgHdrInit(PIPCMSGHDR pMsgHdr, const nsID &target, size_t cbPayload) 135 { 136 Assert(cbPayload == (uint32_t)cbPayload); 137 138 pMsgHdr->cbMsg = sizeof(*pMsgHdr) + (uint32_t)cbPayload; 139 pMsgHdr->u16Version = IPC_MSG_HDR_VERSION; 140 pMsgHdr->u16Flags = 0; 141 pMsgHdr->idTarget = target; 142 143 return pMsgHdr; 144 } 145 146 147 DECLINLINE(void) IPCMsgInitStack(PIPCMSG pThis, const nsID &target, const void *pvData, size_t cbData) 148 { 149 pThis->fStack = true; 150 pThis->fReadonly = true; 151 pThis->pbBuf = (uint8_t *)pvData; 152 pThis->cbBuf = sizeof(*pThis->pMsgHdr) + cbData; 153 pThis->pMsgHdr = (PIPCMSGHDR)pThis->pbBuf; 154 pThis->pMsgHdr->cbMsg = sizeof(*pThis->pMsgHdr) + cbData; 155 pThis->pMsgHdr->u16Version = IPC_MSG_HDR_VERSION; 156 pThis->pMsgHdr->u16Flags = 0; 157 pThis->pMsgHdr->idTarget = target; 158 } 159 160 130 161 DECLINLINE(int) IPCMsgInit(PIPCMSG pThis, size_t cbBuf) 131 162 { … … 155 186 if (RT_UNLIKELY(!pThis)) 156 187 return NULL; 188 189 pThis->fStack = false; 157 190 158 191 if (cbMsg) … … 180 213 DECLINLINE(void) IPCMsgFree(PIPCMSG pThis, bool fFreeStruct) 181 214 { 215 /* Stack based messages are never freed. */ 216 if (pThis->fStack) 217 return; 218 182 219 if (pThis->pbBuf) 183 220 RTMemFree(pThis->pbBuf); … … 316 353 317 354 /** 355 * Clears the given flag in the message header. 356 * 357 * @param pThis The IPC message. 358 * @param fFlag The flag to clear. 359 */ 360 DECLINLINE(void) IPCMsgClearFlag(PIPCMSG pThis, uint16_t fFlag) 361 { 362 pThis->pMsgHdr->u16Flags &= ~fFlag; 363 } 364 365 366 /** 318 367 * Init worker for a given message frame. 319 368 * … … 373 422 DECLINLINE(int) IPCMsgInitSg(PIPCMSG pThis, const nsID &target, size_t cbTotal, PCRTSGSEG paSegs, uint32_t cSegs) 374 423 { 424 Assert(!pThis->fStack); 425 375 426 uint32_t cbMsg = sizeof(*pThis->pMsgHdr) + cbTotal; 376 427 if (pThis->cbBuf < cbMsg) … … 389 440 390 441 442 DECLINLINE(PIPCMSG) IPCMsgClone(PCIPCMSG pThis) 443 { 444 size_t cbPayload = pThis->pMsgHdr->cbMsg - sizeof(*pThis->pMsgHdr); 445 PIPCMSG pClone = IPCMsgAlloc(cbPayload); 446 if (!pClone) 447 return NULL; 448 449 pClone->pMsgHdr = (PIPCMSGHDR)pClone->pbBuf; 450 *pClone->pMsgHdr = *pThis->pMsgHdr; 451 pClone->upUser = pThis->upUser; 452 memcpy(pClone->pMsgHdr + 1, pThis->pMsgHdr + 1, cbPayload); 453 return pClone; 454 } 455 456 457 DECLINLINE(int) IPCMsgCloneWithMsg(PCIPCMSG pThis, PIPCMSG pClone) 458 { 459 RTSGSEG Seg; 460 Seg.pvSeg = (void *)IPCMsgGetPayload(pThis); 461 Seg.cbSeg = IPCMsgGetPayloadSize(pThis); 462 463 pClone->upUser = pThis->upUser; 464 return IPCMsgInitSg(pClone, *IPCMsgGetTarget(pThis), 465 Seg.cbSeg, &Seg, 1 /*cSeg*/); 466 } 467 468 391 469 /** 392 470 * Reads data for the given message from the given buffer. … … 401 479 DECLINLINE(int) IPCMsgReadFrom(PIPCMSG pThis, const void *pvData, size_t cbData, size_t *pcbRead, bool *pfDone) 402 480 { 481 Assert(!pThis->fStack); 482 403 483 size_t cbHdrRead = 0; 404 484 if (!pThis->pMsgHdr) -
trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.cpp
r101966 r103472 36 36 * ***** END LICENSE BLOCK ***** */ 37 37 38 #include <string.h>39 38 #include "ipcm.h" 40 39 … … 49 48 }; 50 49 51 PRUint32 52 IPCM_NewRequestIndex() 50 DECLHIDDEN(uint32_t) IPCM_NewRequestIndex() 53 51 { 54 52 static volatile uint32_t sRequestIndex = 0; 55 53 return ASMAtomicIncU32(&sRequestIndex); 56 54 } 57 58 #if 059 60 //61 // MSG_TYPE values62 //63 const PRUint32 ipcmMessagePing::MSG_TYPE = IPCM_MSG_TYPE_PING;64 const PRUint32 ipcmMessageError::MSG_TYPE = IPCM_MSG_TYPE_ERROR;65 const PRUint32 ipcmMessageClientHello::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_HELLO;66 const PRUint32 ipcmMessageClientID::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ID;67 const PRUint32 ipcmMessageClientInfo::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_INFO;68 const PRUint32 ipcmMessageClientAddName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_NAME;69 const PRUint32 ipcmMessageClientDelName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_NAME;70 const PRUint32 ipcmMessageClientAddTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_TARGET;71 const PRUint32 ipcmMessageClientDelTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_TARGET;72 const PRUint32 ipcmMessageQueryClientByName::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME;73 const PRUint32 ipcmMessageQueryClientInfo::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_INFO;74 const PRUint32 ipcmMessageForward::MSG_TYPE = IPCM_MSG_TYPE_FORWARD;75 const PRUint32 ipcmMessageClientStatus::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_STATUS;76 77 //78 // CLIENT_INFO message79 //80 // +-----------------------------------------+81 // | DWORD : MSG_TYPE |82 // +--------------------+--------------------+83 // | DWORD : clientID |84 // +--------------------+--------------------+85 // | DWORD : requestIndex |86 // +--------------------+--------------------+87 // | WORD : nameStart | WORD : nameCount |88 // +--------------------+--------------------+89 // | WORD : targetStart | WORD : targetCount |90 // +--------------------+--------------------+91 // | name[0] | (null byte) |92 // +--------------------+--------------------+93 // . . .94 // . . .95 // +--------------------+--------------------+96 // | name[count - 1] | (null byte) |97 // +--------------------+--------------------+98 // | target[0] |99 // +-----------------------------------------+100 // . . .101 // . . .102 // +-----------------------------------------+103 // | target[count - 1] |104 // +-----------------------------------------+105 //106 107 struct ipcmClientInfoHeader108 {109 PRUint32 mType;110 PRUint32 mID;111 PRUint32 mRequestIndex;112 PRUint16 mNameStart;113 PRUint16 mNameCount;114 PRUint16 mTargetStart;115 PRUint16 mTargetCount;116 };117 118 ipcmMessageClientInfo::ipcmMessageClientInfo(PRUint32 cID, PRUint32 rIdx, const char *names[], const nsID *targets[])119 {120 ipcmClientInfoHeader hdr = {0};121 122 hdr.mType = MSG_TYPE;123 hdr.mID = cID;124 hdr.mRequestIndex = rIdx;125 hdr.mNameStart = sizeof(hdr);126 127 PRUint32 i, namesLen = 0;128 129 i = 0;130 while (names[i]) {131 namesLen += (strlen(names[i]) + 1);132 ++hdr.mNameCount;133 ++i;134 }135 136 i = 0;137 while (targets[i]) {138 ++hdr.mTargetCount;139 ++i;140 }141 142 //143 // compute target array starting offset144 //145 hdr.mTargetStart = hdr.mNameStart + namesLen;146 147 //148 // compute message length149 //150 PRUint32 dataLen = sizeof(hdr) + namesLen + hdr.mTargetCount * sizeof(nsID);151 152 Init(IPCM_TARGET, NULL, dataLen);153 154 //155 // write message data156 //157 SetData(0, (const char *) &hdr, sizeof(hdr));158 159 PRUint32 offset = sizeof(hdr);160 161 for (i = 0; names[i]; ++i) {162 PRUint32 len = strlen(names[i]) + 1;163 SetData(offset, names[i], len);164 offset += len;165 }166 167 for (i = 0; targets[i]; ++i) {168 PRUint32 len = sizeof(nsID);169 SetData(offset, (const char *) targets[i], len);170 offset += len;171 }172 }173 174 PRUint32175 ipcmMessageClientInfo::ClientID() const176 {177 ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();178 return hdr->mID;179 }180 181 PRUint32182 ipcmMessageClientInfo::RequestIndex() const183 {184 ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();185 return hdr->mRequestIndex;186 }187 188 PRUint32189 ipcmMessageClientInfo::NameCount() const190 {191 ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();192 return hdr->mNameCount;193 }194 195 PRUint32196 ipcmMessageClientInfo::TargetCount() const197 {198 ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();199 return hdr->mTargetCount;200 }201 202 const char *203 ipcmMessageClientInfo::NextName(const char *name) const204 {205 ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();206 207 if (!name)208 return (const char *) hdr + hdr->mNameStart;209 210 name += strlen(name) + 1;211 if (name == (const char *) hdr + hdr->mTargetStart)212 name = NULL;213 return name;214 }215 216 const nsID *217 ipcmMessageClientInfo::NextTarget(const nsID *target) const218 {219 ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();220 221 if (!target)222 return (const nsID *) (Data() + hdr->mTargetStart);223 224 if (++target == (const nsID *) (MsgBuf() + MsgLen()))225 target = NULL;226 return target;227 }228 #endif229 230 //231 // FORWARD message232 //233 // +-------------------------+234 // | DWORD : MSG_TYPE |235 // +-------------------------+236 // | clientID |237 // +-------------------------+238 // | innerMsgHeader |239 // +-------------------------+240 // | innerMsgData |241 // +-------------------------+242 //243 244 ipcmMessageForward::ipcmMessageForward(PRUint32 type,245 PRUint32 cID,246 const nsID &target,247 const char *data,248 PRUint32 dataLen)249 {250 int len = sizeof(ipcmMessageHeader) + // IPCM header251 sizeof(cID) + // cID252 IPC_MSG_HEADER_SIZE + // innerMsgHeader253 dataLen; // innerMsgData254 255 Init(IPCM_TARGET, NULL, len);256 257 ipcmMessageHeader ipcmHdr =258 { type, IPCM_NewRequestIndex() };259 260 SetData(0, (char *) &ipcmHdr, sizeof(ipcmHdr));261 SetData(sizeof(ipcmHdr), (char *) &cID, sizeof(cID));262 263 ipcMessageHeader hdr;264 hdr.mLen = IPC_MSG_HEADER_SIZE + dataLen;265 hdr.mVersion = IPC_MSG_VERSION;266 hdr.mFlags = 0;267 hdr.mTarget = target;268 269 SetData(sizeof(ipcmHdr) + sizeof(cID), (char *) &hdr, IPC_MSG_HEADER_SIZE);270 if (data)271 SetInnerData(0, data, dataLen);272 }273 274 void275 ipcmMessageForward::SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen)276 {277 SetData(sizeof(ipcmMessageHeader) + 4 + IPC_MSG_HEADER_SIZE + offset, data, dataLen);278 }279 280 PRUint32281 ipcmMessageForward::ClientID() const282 {283 return ((PRUint32 *) Data())[2];284 }285 286 const nsID &287 ipcmMessageForward::InnerTarget() const288 {289 ipcMessageHeader *hdr = (ipcMessageHeader *) (Data() + 12);290 return hdr->mTarget;291 }292 293 const char *294 ipcmMessageForward::InnerData() const295 {296 return Data() + 12 + IPC_MSG_HEADER_SIZE;297 }298 299 PRUint32300 ipcmMessageForward::InnerDataLen() const301 {302 ipcMessageHeader *hdr = (ipcMessageHeader *) (Data() + 12);303 return hdr->mLen - IPC_MSG_HEADER_SIZE;304 } -
trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.h
r103378 r103472 41 41 #include <iprt/assertcompile.h> 42 42 43 #include "ipcMessage.h" 44 #include "ipcMessagePrimitives.h" 43 #include "ipcMessageNew.h" 45 44 46 45 //----------------------------------------------------------------------------- … … 115 114 // IPCM header 116 115 // 117 struct ipcmMessageHeader 118 { 119 PRUint32 mType; 120 PRUint32 mRequestIndex; 121 }; 122 AssertCompileSize(struct ipcmMessageHeader, 8); 123 124 // 125 // returns IPCM message type. 126 // 127 static inline int 128 IPCM_GetType(const ipcMessage *msg) 129 { 130 return ((const ipcmMessageHeader *) msg->Data())->mType; 131 } 132 133 // 134 // return IPCM message request index. 135 // 136 static inline PRUint32 137 IPCM_GetRequestIndex(const ipcMessage *msg) 138 { 139 return ((const ipcmMessageHeader *) msg->Data())->mRequestIndex; 140 } 116 typedef struct IPCMMSGHDR 117 { 118 uint32_t u32Type; 119 uint32_t u32RequestIndex; 120 } IPCMMSGHDR; 121 AssertCompileSize(struct IPCMMSGHDR, 8); 122 /** Pointer to an IPCM header. */ 123 typedef IPCMMSGHDR *PIPCMMSGHDR; 124 /** Pointer to a const IPCM header. */ 125 typedef const IPCMMSGHDR *PCIPCMMSGHDR; 126 127 128 DECLINLINE(uint32_t) IPCM_GetType(PCIPCMSG pMsg) 129 { 130 return ((PCIPCMMSGHDR)IPCMsgGetPayload(pMsg))->u32Type; 131 } 132 133 134 DECLINLINE(uint32_t) IPCM_GetRequestIndex(PCIPCMSG pMsg) 135 { 136 return ((PCIPCMMSGHDR)IPCMsgGetPayload(pMsg))->u32RequestIndex; 137 } 138 141 139 142 140 // 143 141 // return a request index that is unique to this process. 144 142 // 145 NS_HIDDEN_(PRUint32) 146 IPCM_NewRequestIndex(); 143 DECLHIDDEN(uint32_t) IPCM_NewRequestIndex(); 147 144 148 145 //----------------------------------------------------------------------------- … … 322 319 // 323 320 324 //-----------------------------------------------------------------------------325 326 //327 // NOTE: This file declares some helper classes that simplify constructing328 // and parsing IPCM messages. Each class subclasses ipcMessage, but329 // adds no additional member variables. |operator new| should be used330 // to allocate one of the IPCM helper classes, e.g.:331 //332 // ipcMessage *msg = new ipcmMessageClientHello("foo");333 //334 // Given an arbitrary ipcMessage, it can be parsed using logic similar335 // to the following:336 //337 // void func(const ipcMessage *unknown)338 // {339 // if (unknown->Topic().Equals(IPCM_TARGET)) {340 // if (IPCM_GetMsgType(unknown) == IPCM_MSG_TYPE_CLIENT_ID) {341 // ipcMessageCast<ipcmMessageClientID> msg(unknown);342 // printf("Client ID: %u\n", msg->ClientID());343 // }344 // }345 // }346 //347 348 321 // REQUESTS 349 322 350 class ipcmMessagePing : public ipcMessage_DWORD_DWORD 351 { 352 public: 353 ipcmMessagePing() 354 : ipcMessage_DWORD_DWORD( 355 IPCM_TARGET, 356 IPCM_MSG_REQ_PING, 357 IPCM_NewRequestIndex()) {} 358 }; 359 360 class ipcmMessageForward : public ipcMessage 361 { 362 public: 363 // @param type the type of this message: IPCM_MSG_{REQ,PSH}_FORWARD 364 // @param clientID the client id of the sender or receiver 365 // @param target the message target 366 // @param data the message data 367 // @param dataLen the message data length 368 ipcmMessageForward(PRUint32 type, 369 PRUint32 clientID, 370 const nsID &target, 371 const char *data, 372 PRUint32 dataLen) NS_HIDDEN; 373 374 // set inner message data, constrained to the data length passed 375 // to this class's constructor. 376 NS_HIDDEN_(void) SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen); 377 378 NS_HIDDEN_(PRUint32) ClientID() const; 379 NS_HIDDEN_(const nsID &) InnerTarget() const; 380 NS_HIDDEN_(const char *) InnerData() const; 381 NS_HIDDEN_(PRUint32) InnerDataLen() const; 382 }; 383 384 class ipcmMessageClientHello : public ipcMessage_DWORD_DWORD 385 { 386 public: 387 ipcmMessageClientHello() 388 : ipcMessage_DWORD_DWORD( 389 IPCM_TARGET, 390 IPCM_MSG_REQ_CLIENT_HELLO, 391 IPCM_NewRequestIndex()) {} 392 }; 393 394 class ipcmMessageClientAddName : public ipcMessage_DWORD_DWORD_STR 395 { 396 public: 397 ipcmMessageClientAddName(const char *name) 398 : ipcMessage_DWORD_DWORD_STR( 399 IPCM_TARGET, 400 IPCM_MSG_REQ_CLIENT_ADD_NAME, 401 IPCM_NewRequestIndex(), 402 name) {} 403 404 const char *Name() const { return Third(); } 405 }; 406 407 class ipcmMessageClientDelName : public ipcMessage_DWORD_DWORD_STR 408 { 409 public: 410 ipcmMessageClientDelName(const char *name) 411 : ipcMessage_DWORD_DWORD_STR( 412 IPCM_TARGET, 413 IPCM_MSG_REQ_CLIENT_DEL_NAME, 414 IPCM_NewRequestIndex(), 415 name) {} 416 417 const char *Name() const { return Third(); } 418 }; 419 420 class ipcmMessageClientAddTarget : public ipcMessage_DWORD_DWORD_ID 421 { 422 public: 423 ipcmMessageClientAddTarget(const nsID &target) 424 : ipcMessage_DWORD_DWORD_ID( 425 IPCM_TARGET, 426 IPCM_MSG_REQ_CLIENT_ADD_TARGET, 427 IPCM_NewRequestIndex(), 428 target) {} 429 430 const nsID &Target() const { return Third(); } 431 }; 432 433 class ipcmMessageClientDelTarget : public ipcMessage_DWORD_DWORD_ID 434 { 435 public: 436 ipcmMessageClientDelTarget(const nsID &target) 437 : ipcMessage_DWORD_DWORD_ID( 438 IPCM_TARGET, 439 IPCM_MSG_REQ_CLIENT_ADD_TARGET, 440 IPCM_NewRequestIndex(), 441 target) {} 442 443 const nsID &Target() const { return Third(); } 444 }; 445 446 class ipcmMessageQueryClientByName : public ipcMessage_DWORD_DWORD_STR 447 { 448 public: 449 ipcmMessageQueryClientByName(const char *name) 450 : ipcMessage_DWORD_DWORD_STR( 451 IPCM_TARGET, 452 IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME, 453 IPCM_NewRequestIndex(), 454 name) {} 455 456 const char *Name() const { return Third(); } 457 PRUint32 RequestIndex() const { return Second(); } 458 }; 323 /** The ping message consists of just the header. */ 324 typedef IPCMMSGHDR IPCMMSGPING; 325 typedef IPCMMSGPING *PIPCMMSGPING; 326 327 DECLINLINE(void) IPCMMsgPingInit(PIPCMMSGPING pThis) 328 { 329 pThis->u32Type = IPCM_MSG_REQ_PING; 330 pThis->u32RequestIndex = IPCM_NewRequestIndex(); 331 } 332 333 334 /** The client hello message consists of just the header. */ 335 typedef IPCMMSGHDR IPCMMSGCLIENTHELLO; 336 typedef IPCMMSGCLIENTHELLO *PIPCMMSGCLIENTHELLO; 337 338 DECLINLINE(void) IPCMMsgClientHelloInit(PIPCMMSGCLIENTHELLO pThis) 339 { 340 pThis->u32Type = IPCM_MSG_REQ_CLIENT_HELLO; 341 pThis->u32RequestIndex = IPCM_NewRequestIndex(); 342 } 343 344 345 typedef struct IPCMMSGFORWARD 346 { 347 IPCMMSGHDR Hdr; 348 uint32_t u32ClientId; 349 } IPCMMSGFORWARD; 350 AssertCompileSize(IPCMMSGFORWARD, 3 * sizeof(uint32_t)); 351 typedef IPCMMSGFORWARD *PIPCMMSGFORWARD; 352 typedef const IPCMMSGFORWARD *PCIPCMMSGFORWARD; 353 354 355 DECLINLINE(int) ipcmMsgInitHdrStr(PIPCMSG pMsg, uint32_t u32Type, const char *psz) 356 { 357 size_t cbStr = strlen(psz) + 1; /* Includes terminator. */ 358 const IPCMMSGHDR Hdr = { u32Type, IPCM_NewRequestIndex() }; 359 RTSGSEG aSegs[2]; 360 361 aSegs[0].pvSeg = (void *)&Hdr; 362 aSegs[0].cbSeg = sizeof(Hdr); 363 364 aSegs[1].pvSeg = (void *)psz; 365 aSegs[1].cbSeg = cbStr; 366 return IPCMsgInitSg(pMsg, IPCM_TARGET, cbStr + sizeof(Hdr), &aSegs[0], RT_ELEMENTS(aSegs)); 367 } 368 369 370 DECLINLINE(int) IPCMMsgClientAddNameInit(PIPCMSG pMsg, const char *pszName) 371 { 372 return ipcmMsgInitHdrStr(pMsg, IPCM_MSG_REQ_CLIENT_ADD_NAME, pszName); 373 } 374 375 376 DECLINLINE(int) IPCMMsgClientDelNameInit(PIPCMSG pMsg, const char *pszName) 377 { 378 return ipcmMsgInitHdrStr(pMsg, IPCM_MSG_REQ_CLIENT_DEL_NAME, pszName); 379 } 380 381 382 typedef struct IPCMMSGCLIENTADDDELTARGET 383 { 384 IPCMMSGHDR Hdr; 385 nsID idTarget; 386 } IPCMMSGCLIENTADDDELTARGET; 387 AssertCompileSize(IPCMMSGCLIENTADDDELTARGET, 2 * sizeof(uint32_t) + sizeof(nsID)); 388 typedef IPCMMSGCLIENTADDDELTARGET *PIPCMMSGCLIENTADDDELTARGET; 389 typedef const IPCMMSGCLIENTADDDELTARGET *PCIPCMMSGCLIENTADDDELTARGET; 390 391 DECLINLINE(void) IPCMMsgAddTargetInit(PIPCMMSGCLIENTADDDELTARGET pThis, const nsID &target) 392 { 393 pThis->Hdr.u32Type = IPCM_MSG_REQ_CLIENT_ADD_TARGET; 394 pThis->Hdr.u32RequestIndex = IPCM_NewRequestIndex(); 395 pThis->idTarget = target; 396 } 397 398 399 DECLINLINE(void) IPCMMsgDelTargetInit(PIPCMMSGCLIENTADDDELTARGET pThis, const nsID &target) 400 { 401 pThis->Hdr.u32Type = IPCM_MSG_REQ_CLIENT_DEL_TARGET; 402 pThis->Hdr.u32RequestIndex = IPCM_NewRequestIndex(); 403 pThis->idTarget = target; 404 } 405 406 407 DECLINLINE(int) IPCMMsgQueryClientByNameInit(PIPCMSG pMsg, const char *pszName) 408 { 409 return ipcmMsgInitHdrStr(pMsg, IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME, pszName); 410 } 411 459 412 460 413 // ACKNOWLEDGEMENTS 461 414 462 class ipcmMessageResult : public ipcMessage_DWORD_DWORD_DWORD 463 { 464 public: 465 ipcmMessageResult(PRUint32 requestIndex, PRInt32 status) 466 : ipcMessage_DWORD_DWORD_DWORD( 467 IPCM_TARGET, 468 IPCM_MSG_ACK_RESULT, 469 requestIndex, 470 (PRUint32) status) {} 471 472 PRInt32 Status() const { return (PRInt32) Third(); } 473 }; 474 475 class ipcmMessageClientID : public ipcMessage_DWORD_DWORD_DWORD 476 { 477 public: 478 ipcmMessageClientID(PRUint32 requestIndex, PRUint32 clientID) 479 : ipcMessage_DWORD_DWORD_DWORD( 480 IPCM_TARGET, 481 IPCM_MSG_ACK_CLIENT_ID, 482 requestIndex, 483 clientID) {} 484 485 PRUint32 ClientID() const { return Third(); } 486 }; 415 typedef struct IPCMMSGRESULT 416 { 417 IPCMMSGHDR Hdr; 418 int32_t i32Status; 419 } IPCMMSGRESULT; 420 AssertCompileSize(IPCMMSGRESULT, 3 * sizeof(uint32_t)); 421 typedef IPCMMSGRESULT *PIPCMMSGRESULT; 422 typedef const IPCMMSGRESULT *PCIPCMMSGRESULT; 423 424 typedef struct IPCMMSGCLIENTID 425 { 426 IPCMMSGHDR Hdr; 427 uint32_t u32ClientId; 428 } IPCMMSGCLIENTID; 429 AssertCompileSize(IPCMMSGCLIENTID, 3 * sizeof(uint32_t)); 430 typedef IPCMMSGCLIENTID *PIPCMMSGCLIENTID; 431 typedef const IPCMMSGCLIENTID *PCIPCMMSGCLIENTID; 432 487 433 488 434 // PUSH MESSAGES 489 435 490 class ipcmMessageClientState : public ipcMessage_DWORD_DWORD_DWORD_DWORD 491 { 492 public: 493 ipcmMessageClientState(PRUint32 clientID, PRUint32 clientStatus) 494 : ipcMessage_DWORD_DWORD_DWORD_DWORD( 495 IPCM_TARGET, 496 IPCM_MSG_PSH_CLIENT_STATE, 497 0, 498 clientID, 499 clientStatus) {} 500 501 PRUint32 ClientID() const { return Third(); } 502 PRUint32 ClientState() const { return Fourth(); } 503 }; 436 typedef struct IPCMMSGCLIENTSTATE 437 { 438 IPCMMSGHDR Hdr; 439 uint32_t u32ClientId; 440 uint32_t u32ClientStatus; 441 } IPCMMSGCLIENTSTATE; 442 AssertCompileSize(IPCMMSGCLIENTSTATE, 4 * sizeof(uint32_t)); 443 typedef IPCMMSGCLIENTSTATE *PIPCMMSGCLIENTSTATE; 444 typedef const IPCMMSGCLIENTSTATE *PCIPCMMSGCLIENTSTATE; 445 446 /** 447 * Helper structure for stack based messages. 448 */ 449 typedef struct IPCMMSGSTACK 450 { 451 IPCMSGHDR Hdr; 452 union 453 { 454 IPCMMSGHDR Hdr; 455 IPCMMSGPING Ping; 456 IPCMMSGCLIENTHELLO ClientHello; 457 IPCMMSGCLIENTADDDELTARGET AddDelTarget; 458 IPCMMSGRESULT Result; 459 IPCMMSGCLIENTID ClientId; 460 IPCMMSGCLIENTSTATE ClientState; 461 } Ipcm; 462 } IPCMMSGSTACK; 504 463 505 464 #endif // !ipcm_h__
Note:
See TracChangeset
for help on using the changeset viewer.