Changeset 7029 in vbox for trunk/src/libs/xpcom18a4
- Timestamp:
- Feb 20, 2008 11:54:09 AM (17 years ago)
- Location:
- trunk/src/libs/xpcom18a4/ipc/ipcd
- Files:
-
- 7 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 } -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcClient.cpp
r1 r7029 96 96 } 97 97 98 void 98 PRBool 99 99 ipcClient::DelName(const char *name) 100 100 { 101 101 LOG(("deleting client name: %s\n", name)); 102 102 103 mNames.FindAndDelete(name);103 return mNames.FindAndDelete(name); 104 104 } 105 105 … … 115 115 } 116 116 117 void 117 PRBool 118 118 ipcClient::DelTarget(const nsID &target) 119 119 { … … 124 124 // 125 125 if (!target.Equals(IPCM_TARGET)) 126 mTargets.FindAndDelete(target); 126 return mTargets.FindAndDelete(target); 127 128 return PR_FALSE; 127 129 } 128 130 … … 185 187 } 186 188 } 187 189 188 190 if (inFlags & PR_POLL_WRITE) { 189 191 LOG(("client socket is now writable\n")); -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcClient.h
r1 r7029 65 65 66 66 void AddName(const char *name); 67 voidDelName(const char *name);67 PRBool DelName(const char *name); 68 68 PRBool HasName(const char *name) const { return mNames.Find(name) != NULL; } 69 69 70 70 void AddTarget(const nsID &target); 71 voidDelTarget(const nsID &target);71 PRBool DelTarget(const nsID &target); 72 72 PRBool HasTarget(const nsID &target) const { return mTargets.Find(target) != NULL; } 73 73 … … 96 96 // 97 97 // returns: 98 // 0 - to cancel client connection 98 // 0 - to cancel client connection 99 99 // PR_POLL_READ - to poll for a readable socket 100 100 // PR_POLL_WRITE - to poll for a writable socket … … 102 102 // 103 103 // the socket is non-blocking. 104 // 104 // 105 105 int Process(PRFileDesc *sockFD, int pollFlags); 106 106 … … 125 125 // encoded in it. 126 126 PRUint32 mPID; 127 127 128 128 // the hwnd of the client's message window. 129 129 HWND mHwnd; -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcCommandModule.cpp
r1 r7029 62 62 63 63 const ipcStringNode *node; 64 64 65 65 for (node = nodes; node; node = node->mNext) 66 66 count++; … … 84 84 85 85 const ipcIDNode *node; 86 86 87 87 for (node = nodes; node; node = node->mNext) 88 88 count++; … … 133 133 LOG(("got CLIENT_ADD_NAME\n")); 134 134 135 PRInt32 status = IPCM_OK; 136 PRUint32 requestIndex = IPCM_GetRequestIndex(rawMsg); 137 135 138 ipcMessageCast<ipcmMessageClientAddName> msg(rawMsg); 136 139 const char *name = msg->Name(); 137 if (name) 138 client->AddName(name); 139 140 // TODO: send better status code (e.g., suppose name already defined for client) 141 IPC_SendMsg(client, new ipcmMessageResult(IPCM_GetRequestIndex(rawMsg), IPCM_OK)); 140 if (name) { 141 ipcClient *result = IPC_GetClientByName(msg->Name()); 142 if (result) { 143 LOG((" client with such name already exists (ID = %d)\n", result->ID())); 144 status = IPCM_ERROR_ALREADY_EXISTS; 145 } 146 else 147 client->AddName(name); 148 } 149 else 150 status = IPCM_ERROR_INVALID_ARG; 151 152 IPC_SendMsg(client, new ipcmMessageResult(requestIndex, status)); 142 153 } 143 154 … … 146 157 { 147 158 LOG(("got CLIENT_DEL_NAME\n")); 159 160 PRInt32 status = IPCM_OK; 161 PRUint32 requestIndex = IPCM_GetRequestIndex(rawMsg); 148 162 149 163 ipcMessageCast<ipcmMessageClientDelName> msg(rawMsg); 150 164 const char *name = msg->Name(); 151 if (name) 152 client->DelName(name); 153 154 // TODO: send better status code (e.g., suppose name not defined for client) 155 IPC_SendMsg(client, new ipcmMessageResult(IPCM_GetRequestIndex(rawMsg), IPCM_OK)); 165 if (name) { 166 if (!client->DelName(name)) { 167 LOG((" client doesn't have name '%s'\n", name)); 168 status = IPCM_ERROR_NO_SUCH_DATA; 169 } 170 } 171 else 172 status = IPCM_ERROR_INVALID_ARG; 173 174 IPC_SendMsg(client, new ipcmMessageResult(requestIndex, status)); 156 175 } 157 176 … … 161 180 LOG(("got CLIENT_ADD_TARGET\n")); 162 181 182 PRInt32 status = IPCM_OK; 183 PRUint32 requestIndex = IPCM_GetRequestIndex(rawMsg); 184 163 185 ipcMessageCast<ipcmMessageClientAddTarget> msg(rawMsg); 164 client->AddTarget(msg->Target()); 165 166 // TODO: send better status code (e.g., suppose target already defined for client) 167 IPC_SendMsg(client, new ipcmMessageResult(IPCM_GetRequestIndex(rawMsg), IPCM_OK)); 186 if (client->HasTarget(msg->Target())) { 187 LOG((" target already defined for client\n")); 188 status = IPCM_ERROR_ALREADY_EXISTS; 189 } 190 else 191 client->AddTarget(msg->Target()); 192 193 IPC_SendMsg(client, new ipcmMessageResult(requestIndex, status)); 168 194 } 169 195 … … 173 199 LOG(("got CLIENT_DEL_TARGET\n")); 174 200 201 PRInt32 status = IPCM_OK; 202 PRUint32 requestIndex = IPCM_GetRequestIndex(rawMsg); 203 175 204 ipcMessageCast<ipcmMessageClientDelTarget> msg(rawMsg); 176 client->DelTarget(msg->Target()); 177 178 // TODO: send better status code (e.g., suppose target not defined for client) 179 IPC_SendMsg(client, new ipcmMessageResult(IPCM_GetRequestIndex(rawMsg), IPCM_OK)); 205 if (!client->DelTarget(msg->Target())) { 206 LOG((" client doesn't have the given target\n")); 207 status = IPCM_ERROR_NO_SUCH_DATA; 208 } 209 210 IPC_SendMsg(client, new ipcmMessageResult(requestIndex, status)); 180 211 } 181 212 … … 222 253 else { 223 254 LOG((" client does not exist\n")); 224 IPC_SendMsg(client, new ipcmMessageError(IPCM_ERROR_ CLIENT_NOT_FOUND, msg->RequestIndex()));255 IPC_SendMsg(client, new ipcmMessageError(IPCM_ERROR_NO_CLIENT, msg->RequestIndex())); 225 256 } 226 257 } … … 278 309 type--; 279 310 if (type < 0 || type >= (int) (sizeof(handlers)/sizeof(handlers[0]))) { 280 LOG(("unknown request -- ignoring message\n")); 311 LOG(("unknown request -- ignoring message\n")); 281 312 return; 282 313 } -
trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcIDList.h
r1 r7029 86 86 } 87 87 88 voidFindAndDelete(const nsID &id)88 PRBool FindAndDelete(const nsID &id) 89 89 { 90 90 ipcIDNode *node = FindNodeBefore(mHead, id); 91 if (node) 91 if (node) { 92 92 DeleteAfter(node); 93 else 93 return PR_TRUE; 94 } 95 else if (!IsEmpty()) { 94 96 DeleteFirst(); 97 return PR_TRUE; 98 } 99 100 return PR_FALSE; 95 101 } 96 102 -
trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcStringList.h
r1 r7029 92 92 } 93 93 94 voidFindAndDelete(const char *str)94 PRBool FindAndDelete(const char *str) 95 95 { 96 96 ipcStringNode *node = FindNodeBefore(mHead, str); 97 if (node) 97 if (node) { 98 98 DeleteAfter(node); 99 else 99 return PR_TRUE; 100 } 101 else if (!IsEmpty()) { 100 102 DeleteFirst(); 103 return PR_TRUE; 104 } 105 106 return PR_FALSE; 101 107 } 102 108 -
trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.h
r1 r7029 129 129 130 130 // 131 // return IPCM message request index. 131 // return IPCM message request index. 132 132 // 133 133 static inline PRUint32 … … 258 258 // This request message has as its payload a null-terminated ASCII character 259 259 // string indicating the client name to query. 260 // 260 // 261 261 262 262 // ACKNOWLEDGEMENTS … … 272 272 // codes): 273 273 // 274 #define IPCM_OK 0 // success: generic 275 #define IPCM_ERROR_GENERIC -1 // failure: generic 276 #define IPCM_ERROR_NO_CLIENT -2 // failure: client does not exist 274 #define IPCM_OK 0 // success: generic 275 #define IPCM_ERROR_GENERIC -1 // failure: generic 276 #define IPCM_ERROR_NO_CLIENT -2 // failure: client does not exist 277 #define IPCM_ERROR_INVALID_ARG -3 // failure: invalid request argument 278 #define IPCM_ERROR_NO_SUCH_DATA -4 // failure: requested data does not exist 279 #define IPCM_ERROR_ALREADY_EXISTS -5 // failure: data to set already exists 277 280 278 281 // … … 310 313 // This message is sent by the daemon to a client on behalf of another client. 311 314 // The recipient is expected to unpack the contained message and process it. 312 // 315 // 313 316 // The payload of this message matches the payload of IPCM_MSG_REQ_FORWARD, 314 317 // with the exception that the clientID field is set to the clientID of the … … 323 326 // adds no additional member variables. |operator new| should be used 324 327 // to allocate one of the IPCM helper classes, e.g.: 325 // 328 // 326 329 // ipcMessage *msg = new ipcmMessageClientHello("foo"); 327 330 //
Note:
See TracChangeset
for help on using the changeset viewer.