Changeset 26582 in vbox
- Timestamp:
- Feb 16, 2010 3:01:50 PM (15 years ago)
- Location:
- trunk/src/libs/xpcom18a4/ipc/ipcd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
r26566 r26582 405 405 break; 406 406 } 407 #ifdef VBOX 408 else 409 { 410 /* Special client liveness check if there is no message to process. 411 * This is necessary as there might be several threads waiting for 412 * a message from a single client, and only one gets the DOWN msg. */ 413 PRBool alive = (aSelector)(aArg, td, NULL); 414 if (!alive) 415 { 416 *aMsg = NULL; 417 break; 418 } 419 } 420 #endif /* VBOX */ 407 421 408 422 PRIntervalTime t = PR_IntervalNow(); … … 587 601 WaitIPCMResponseSelector(void *arg, ipcTargetData *td, const ipcMessage *msg) 588 602 { 603 #ifdef VBOX 604 if (!msg) 605 return PR_TRUE; 606 #endif /* VBOX */ 589 607 PRUint32 requestIndex = *(PRUint32 *) arg; 590 608 return IPCM_GetRequestIndex(msg) == requestIndex; … … 914 932 { 915 933 WaitMessageSelectorData *data = (WaitMessageSelectorData *) arg; 934 #ifdef VBOX 935 if (!msg) 936 { 937 /* Special NULL message which asks to check whether the client is 938 * still alive. Called when there is nothing suitable in the queue. */ 939 ipcIMessageObserver *obs = data->observer; 940 if (!obs) 941 obs = td->observer; 942 NS_ASSERTION(obs, "must at least have a default observer"); 943 944 nsresult rv = obs->OnMessageAvailable(IPC_SENDER_ANY, nsID(), 0, 0); 945 if (rv != IPC_WAIT_NEXT_MESSAGE) 946 { 947 data->senderDead = PR_TRUE; 948 return PR_FALSE; 949 } 950 return PR_TRUE; 951 } 952 #endif /* VBOX */ 916 953 917 954 // process the specially forwarded client state message to see if the … … 943 980 { 944 981 // otherwise inform the observer about the client death using a special 945 // null message with an emp ly target id, and fail IPC_WaitMessage call982 // null message with an empty target id, and fail IPC_WaitMessage call 946 983 // with NS_ERROR_xxx only if the observer accepts this message. 947 984 … … 959 996 } 960 997 } 998 #ifdef VBOX 999 else if ((data->senderID == IPC_SENDER_ANY || 1000 status->ClientID() == data->senderID) && 1001 status->ClientState() == IPCM_CLIENT_STATE_UP) 1002 { 1003 LOG(("sender (%d) we're waiting a message from (%d) has come up\n", 1004 status->ClientID(), data->senderID)); 1005 if (data->senderID == IPC_SENDER_ANY) 1006 { 1007 // inform the observer about the client appearance using a special 1008 // null message with an empty target id, but a length of 1. 1009 1010 ipcIMessageObserver *obs = data->observer; 1011 if (!obs) 1012 obs = td->observer; 1013 NS_ASSERTION(obs, "must at least have a default observer"); 1014 1015 nsresult rv = obs->OnMessageAvailable(status->ClientID(), nsID(), 0, 1); 1016 /* VBoxSVC/VBoxXPCOMIPCD auto-start can cause that a client up 1017 * message arrives while we're already waiting for a response 1018 * from this client. Don't declare the connection as dead in 1019 * this case. A client ID wraparound can't falsely trigger 1020 * this, since the waiting thread would have hit the liveness 1021 * check in the mean time. Also, DO NOT consume the message, 1022 * otherwise it gets passed to the DConnect message handling 1023 * without any further checks. IPCM messages are automatically 1024 * discarded if they are left unclaimed. */ 1025 } 1026 } 1027 #endif /* VBOX */ 961 1028 break; 962 1029 } -
trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
r26566 r26582 51 51 #include "nsDeque.h" 52 52 #include "xptcall.h" 53 54 #ifdef VBOX 55 #include <map> 56 #include <list> 57 #endif /* VBOX */ 53 58 54 59 #if defined(DCONNECT_MULTITHREADED) … … 1255 1260 //----------------------------------------------------------------------------- 1256 1261 1262 #ifdef VBOX 1263 typedef struct ClientDownInfo 1264 { 1265 ClientDownInfo(PRUint32 aClient) 1266 { 1267 uClient = aClient; 1268 uTimestamp = PR_IntervalNow(); 1269 } 1270 1271 PRUint32 uClient; 1272 PRIntervalTime uTimestamp; 1273 } ClientDownInfo; 1274 typedef std::map<PRUint32, ClientDownInfo *> ClientDownMap; 1275 typedef std::list<ClientDownInfo *> ClientDownList; 1276 1277 #define MAX_CLIENT_DOWN_SIZE 10000 1278 1279 /* Protected by the queue monitor. */ 1280 static ClientDownMap g_ClientDownMap; 1281 static ClientDownList g_ClientDownList; 1282 1283 #endif /* VBOX */ 1284 1257 1285 class DConnectMsgSelector : public ipcIMessageObserver 1258 1286 { … … 1275 1303 // accept special "client dead" messages for a given peer 1276 1304 // (empty target id, zero data and data length) 1305 #ifndef VBOX 1277 1306 if (aSenderID == mPeer && aTarget.Equals(nsID()) && !aData && !aDataLen) 1278 1307 return NS_OK; 1308 #else /* VBOX */ 1309 if (aSenderID != IPC_SENDER_ANY && aTarget.Equals(nsID()) && !aData && !aDataLen) 1310 { 1311 // Insert new client down information. Start by expiring outdated 1312 // entries and free one element if there's still no space (if needed). 1313 PRIntervalTime now = PR_IntervalNow(); 1314 do { 1315 ClientDownInfo *cInfo = g_ClientDownList.back(); 1316 if (!cInfo) 1317 break; 1318 PRInt64 diff = (PRInt64)now - cInfo->uTimestamp; 1319 if (diff < 0) 1320 diff += (PRInt64)((PRIntervalTime)-1) + 1; 1321 if (diff > PR_SecondsToInterval(15 * 60)) 1322 { 1323 g_ClientDownMap.erase(cInfo->uClient); 1324 g_ClientDownList.pop_back(); 1325 delete cInfo; 1326 } 1327 else 1328 break; 1329 } while (true); 1330 1331 ClientDownMap::iterator it = g_ClientDownMap.find(aSenderID); 1332 if (it == g_ClientDownMap.end()) 1333 { 1334 while (g_ClientDownList.size() >= MAX_CLIENT_DOWN_SIZE) 1335 { 1336 ClientDownInfo *cInfo = g_ClientDownList.back(); 1337 g_ClientDownMap.erase(cInfo->uClient); 1338 g_ClientDownList.pop_back(); 1339 delete cInfo; 1340 } 1341 1342 ClientDownInfo *cInfo = new ClientDownInfo(aSenderID); 1343 g_ClientDownMap[aSenderID] = cInfo; 1344 g_ClientDownList.push_front(cInfo); 1345 } 1346 return (aSenderID == mPeer) ? NS_OK : IPC_WAIT_NEXT_MESSAGE; 1347 } 1348 // accept special "client up" messages for a given peer 1349 // (empty target id, zero data and data length=1) 1350 if (aTarget.Equals(nsID()) && !aData && aDataLen == 1) 1351 { 1352 ClientDownMap::iterator it = g_ClientDownMap.find(aSenderID); 1353 if (it != g_ClientDownMap.end()) 1354 { 1355 ClientDownInfo *cInfo = it->second; 1356 g_ClientDownMap.erase(it); 1357 g_ClientDownList.remove(cInfo); 1358 delete cInfo; 1359 } 1360 return (aSenderID == mPeer) ? NS_OK : IPC_WAIT_NEXT_MESSAGE; 1361 } 1362 // accept special "client check" messages for an anonymous sender 1363 // (invalid sender id, empty target id, zero data and data length 1364 if (aSenderID == IPC_SENDER_ANY && aTarget.Equals(nsID()) && !aData && !aDataLen) 1365 { 1366 LOG(("DConnectMsgSelector::OnMessageAvailable: poll liveness for mPeer=%d\n", 1367 mPeer)); 1368 ClientDownMap::iterator it = g_ClientDownMap.find(mPeer); 1369 return (it == g_ClientDownMap.end()) ? IPC_WAIT_NEXT_MESSAGE : NS_OK; 1370 } 1371 #endif /* VBOX */ 1279 1372 const DConnectOp *op = (const DConnectOp *) aData; 1280 1373 // accept only reply messages with the given peer/opcode/index
Note:
See TracChangeset
for help on using the changeset viewer.