Changeset 7029 in vbox for trunk/src/libs/xpcom18a4/ipc/ipcd/client
- Timestamp:
- Feb 20, 2008 11:54:09 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
r5522 r7029 84 84 // the message observer is called via this event queue 85 85 nsCOMPtr<nsIEventQueue> eventQ; 86 86 87 87 // incoming messages are added to this list 88 88 ipcMessageQ pendingQ; … … 138 138 /* ------------------------------------------------------------------------- */ 139 139 140 typedef nsRefPtrHashtable<nsIDHashKey, ipcTargetData> ipcTargetMap; 140 typedef nsRefPtrHashtable<nsIDHashKey, ipcTargetData> ipcTargetMap; 141 141 142 142 class ipcClientState … … 152 152 153 153 // 154 // the monitor protects the targetMap and the connected and shutdown flags. 154 // the monitor protects the targetMap and the connected and shutdown flags. 155 155 // 156 156 // NOTE: we use a PRMonitor for this instead of a PRLock because we need … … 165 165 166 166 // our process's client id 167 PRUint32 selfID; 167 PRUint32 selfID; 168 168 169 169 nsCOMArray<ipcIClientObserver> clientObservers; … … 319 319 320 320 PRBool isIPCMTarget = aTarget.Equals(IPCM_TARGET); 321 321 322 322 PRIntervalTime timeStart = PR_IntervalNow(); 323 323 PRIntervalTime timeEnd; … … 342 342 // only the ICPM target is allowed to wait for a message after shutdown 343 343 // (but before disconnection). this gives client observers called from 344 // IPC_Shutdown a chance to use IPC_SendMessage to send necessary 344 // IPC_Shutdown a chance to use IPC_SendMessage to send necessary 345 345 // "last minute" messages to other clients. 346 346 347 347 while (gClientState->connected && (!gClientState->shutdown || isIPCMTarget)) 348 348 { … … 375 375 // to guarantee that every message is processed only once. 376 376 // 377 377 378 378 if (!lastChecked->TestFlag(IPC_MSG_FLAG_IN_PROCESS)) 379 379 { … … 381 381 PRBool accepted = (aSelector)(aArg, td, lastChecked); 382 382 lastChecked->ClearFlag(IPC_MSG_FLAG_IN_PROCESS); 383 383 384 384 if (accepted) 385 385 { … … 399 399 lastChecked = lastChecked->mNext; 400 400 } 401 401 402 402 if (*aMsg) 403 403 { … … 517 517 CallProcessPendingQ(const nsID &target, ipcTargetData *td) 518 518 { 519 // we assume that we are inside td's monitor 519 // we assume that we are inside td's monitor 520 520 521 521 PLEvent *ev = new ipcEvent_ProcessPendingQ(target); … … 562 562 /* ------------------------------------------------------------------------- */ 563 563 564 // converts IPCM_ERROR_* status codes to NS_ERROR_* status codes 565 static nsresult nsresult_from_ipcm_result(PRInt32 status) 566 { 567 nsresult rv = NS_ERROR_FAILURE; 568 569 switch (status) 570 { 571 case IPCM_ERROR_GENERIC: rv = NS_ERROR_FAILURE; break; 572 case IPCM_ERROR_INVALID_ARG: rv = NS_ERROR_INVALID_ARG; break; 573 // TODO: select better mapping for the below codes 574 case IPCM_ERROR_NO_CLIENT: 575 case IPCM_ERROR_NO_SUCH_DATA: 576 case IPCM_ERROR_ALREADY_EXISTS: rv = NS_ERROR_FAILURE; break; 577 default: NS_ASSERTION(PR_FALSE, "No conversion"); 578 } 579 580 return rv; 581 } 582 583 /* ------------------------------------------------------------------------- */ 584 564 585 // selects the next IPCM message with matching request index 565 586 static PRBool … … 571 592 572 593 // wait for an IPCM response message. if responseMsg is null, then it is 573 // assumed that the caller does not care to get a reference to the 594 // assumed that the caller does not care to get a reference to the 574 595 // response itself. if the response is an IPCM_MSG_ACK_RESULT, then the 575 596 // status code is mapped to a nsresult and returned by this function. … … 588 609 ipcMessageCast<ipcmMessageResult> result(msg); 589 610 if (result->Status() < 0) 590 rv = NS_ERROR_FAILURE; // XXX nsresult_from_ipcm_result()611 rv = nsresult_from_ipcm_result(result->Status()); 591 612 else 592 613 rv = NS_OK; … … 682 703 if (NS_FAILED(rv)) 683 704 return rv; 684 705 685 706 rv = IPC_Connect(dpath.get()); 686 707 if (NS_FAILED(rv)) … … 742 763 743 764 LOG(("IPC_Shutdown: connected=%d\n",gClientState->connected)); 744 765 745 766 if (gClientState->connected) 746 767 { … … 748 769 // first, set the shutdown flag and unblock any calls to WaitTarget. 749 770 // all targets but IPCM will not be able to use WaitTarget any more. 750 771 751 772 nsAutoMonitor mon(gClientState->monitor); 752 773 gClientState->shutdown = PR_TRUE; … … 759 780 // (this is essential for the DConnect extension, for example, to do the 760 781 // proper uninitialization). 761 782 762 783 ipcEvent_ClientState *ev = new ipcEvent_ClientState(IPC_SENDER_ANY, 763 784 IPCM_CLIENT_STATE_DOWN); 764 785 ipcEvent_ClientState::HandleEvent (ev); 765 786 ipcEvent_ClientState::DestroyEvent (ev); 766 787 767 788 IPC_Disconnect(); 768 789 } … … 896 917 // process the specially forwarded client state message to see if the 897 918 // sender we're waiting a message from has died. 898 919 899 920 if (msg->Target().Equals(IPCM_TARGET)) 900 921 { … … 910 931 LOG(("sender (%d) we're waiting a message from (%d) has died\n", 911 932 status->ClientID(), data->senderID)); 912 933 913 934 if (data->senderID != IPC_SENDER_ANY) 914 935 { 915 936 // we're waiting on a particular client, so IPC_WaitMessage must 916 937 // definitely fail with the NS_ERROR_xxx result. 917 938 918 939 data->senderDead = PR_TRUE; 919 940 return PR_TRUE; // consume the message … … 929 950 obs = td->observer; 930 951 NS_ASSERTION(obs, "must at least have a default observer"); 931 952 932 953 nsresult rv = obs->OnMessageAvailable(status->ClientID(), nsID(), 0, 0); 933 954 if (rv != IPC_WAIT_NEXT_MESSAGE) … … 986 1007 if (NS_FAILED(rv)) 987 1008 return rv; 988 1009 989 1010 // if the requested sender has died while waiting, return an error 990 1011 if (data.senderDead) 991 1012 return NS_ERROR_ABORT; // XXX better error code? 992 1013 993 1014 // if the selector has accepted some message, then we pass it to aConsumer 994 1015 // for safe processing. The IPC susbsystem is quite stable here (i.e. we're … … 1002 1023 msg->DataLen()); 1003 1024 } 1004 1025 1005 1026 delete msg; 1006 1027 … … 1081 1102 rv = NS_ERROR_UNEXPECTED; 1082 1103 } 1083 1104 1084 1105 delete msg; 1085 1106 return rv; … … 1225 1246 PlaceOnPendingQ(aKey, aData, msg->Clone()); 1226 1247 } 1227 1248 1228 1249 return PL_DHASH_NEXT; 1229 1250 } … … 1276 1297 PostEventToMainThread(new ipcEvent_ClientState(status->ClientID(), 1277 1298 status->ClientState())); 1278 1299 1279 1300 // go through the target map, and place this message to every target's 1280 1301 // pending event queue. that unblocks all WaitTarget calls (on all … … 1285 1306 1286 1307 delete msg; 1287 1308 1288 1309 return; 1289 1310 } … … 1295 1316 { 1296 1317 // make copy of target since |msg| may end up pointing to free'd memory 1297 // once we notify the monitor inside PlaceOnPendingQ(). 1318 // once we notify the monitor inside PlaceOnPendingQ(). 1298 1319 const nsID target = msg->Target(); 1299 1320 1300 1321 PlaceOnPendingQ(target, td, msg); 1301 1322 }
Note:
See TracChangeset
for help on using the changeset viewer.