Changeset 26554 in vbox
- Timestamp:
- Feb 15, 2010 6:13:54 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
r7049 r26554 43 43 #include "ipcLog.h" 44 44 #include "ipcm.h" 45 #include "iprt/thread.h" 45 46 46 47 #include "nsIFile.h" … … 405 406 break; 406 407 } 408 #ifdef VBOX 409 else 410 { 411 /* Special client liveness check if there is no message to process. 412 * This is necessary as there might be several threads waiting for 413 * a message from a single client, and only one gets the DOWN msg. */ 414 PRBool alive = (aSelector)(aArg, td, NULL); 415 if (!alive) 416 { 417 *aMsg = NULL; 418 break; 419 } 420 } 421 #endif /* VBOX */ 407 422 408 423 PRIntervalTime t = PR_IntervalNow(); … … 587 602 WaitIPCMResponseSelector(void *arg, ipcTargetData *td, const ipcMessage *msg) 588 603 { 604 #ifdef VBOX 605 if (!msg) 606 return PR_TRUE; 607 #endif /* VBOX */ 589 608 PRUint32 requestIndex = *(PRUint32 *) arg; 590 609 return IPCM_GetRequestIndex(msg) == requestIndex; … … 914 933 { 915 934 WaitMessageSelectorData *data = (WaitMessageSelectorData *) arg; 935 #ifdef VBOX 936 if (!msg) 937 { 938 /* Special NULL message which asks to check whether the client is 939 * still alive. Called when there is nothing suitable in the queue. */ 940 ipcIMessageObserver *obs = data->observer; 941 if (!obs) 942 obs = td->observer; 943 NS_ASSERTION(obs, "must at least have a default observer"); 944 945 nsresult rv = obs->OnMessageAvailable(IPC_SENDER_ANY, nsID(), 0, 0); 946 if (rv != IPC_WAIT_NEXT_MESSAGE) 947 { 948 data->senderDead = PR_TRUE; 949 return PR_FALSE; 950 } 951 return PR_TRUE; 952 } 953 #endif /* VBOX */ 916 954 917 955 // process the specially forwarded client state message to see if the … … 943 981 { 944 982 // otherwise inform the observer about the client death using a special 945 // null message with an emp ly target id, and fail IPC_WaitMessage call983 // null message with an empty target id, and fail IPC_WaitMessage call 946 984 // with NS_ERROR_xxx only if the observer accepts this message. 947 985 … … 959 997 } 960 998 } 999 #ifdef VBOX 1000 else if ((data->senderID == IPC_SENDER_ANY || 1001 status->ClientID() == data->senderID) && 1002 status->ClientState() == IPCM_CLIENT_STATE_UP) 1003 { 1004 LOG(("sender (%d) we're waiting a message from (%d) has come up\n", 1005 status->ClientID(), data->senderID)); 1006 if (data->senderID == IPC_SENDER_ANY) 1007 { 1008 // inform the observer about the client appearance using a special 1009 // null message with an empty target id, but a length of 1. 1010 1011 ipcIMessageObserver *obs = data->observer; 1012 if (!obs) 1013 obs = td->observer; 1014 NS_ASSERTION(obs, "must at least have a default observer"); 1015 1016 nsresult rv = obs->OnMessageAvailable(status->ClientID(), nsID(), 0, 1); 1017 if (rv != IPC_WAIT_NEXT_MESSAGE) 1018 { 1019 /* It might sound a bit paradoxical to declare the sender as 1020 * dead, but the fact that a client up message is received 1021 * while waiting for a message from this client clearly 1022 * indicates that this is no longer the client we were waiting 1023 * for, but a new one got the same client ID (due to wraparound). 1024 * Shouldn't happen in real life, but better be safe. */ 1025 data->senderDead = PR_TRUE; 1026 return PR_TRUE; // consume the message 1027 } 1028 } 1029 } 1030 #endif /* VBOX */ 961 1031 break; 962 1032 } -
trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
r24637 r26554 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.