Changeset 41178 in vbox
- Timestamp:
- May 6, 2012 5:11:18 AM (13 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/slirp.c
r40837 r41178 267 267 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 268 268 }; 269 270 /** 271 * This helper routine do the checks in descriptions to 272 * ''fUnderPolling'' and ''fShouldBeRemoved'' flags 273 * @returns 1 if socket removed and 0 if no changes was made. 274 */ 275 static int slirpVerifyAndFreeSocket(PNATState pData, struct socket *pSocket) 276 { 277 AssertPtrReturn(pData, 0); 278 AssertPtrReturn(pSocket, 0); 279 AssertReturn(pSocket->fUnderPolling, 0); 280 if (pSocket->fShouldBeRemoved) 281 { 282 pSocket->fUnderPolling = 0; 283 sofree(pData, pSocket); 284 /* so is PHANTOM, now */ 285 return 1; 286 } 287 return 0; 288 } 269 289 270 290 #ifdef RT_OS_WINDOWS … … 1238 1258 CONTINUE(tcp); 1239 1259 1260 Assert(!so->fUnderPolling); 1261 so->fUnderPolling = 1; 1240 1262 POLL_TCP_EVENTS(rc, error, so, &NetworkEvents); 1241 1263 … … 1266 1288 { 1267 1289 sorecvoob(pData, so); 1290 if (slirpVerifyAndFreeSocket(pData, so)) 1291 CONTINUE(tcp); 1268 1292 } 1269 1293 … … 1282 1306 bool fRet = slirpConnectOrWrite(pData, so, true); 1283 1307 LogFunc(("fRet:%RTbool\n", fRet)); 1308 if (slirpVerifyAndFreeSocket(pData, so)) 1309 CONTINUE(tcp); 1284 1310 } 1285 1311 #endif … … 1290 1316 { 1291 1317 TCP_CONNECT(pData, so); 1318 if (slirpVerifyAndFreeSocket(pData, so)) 1319 CONTINUE(tcp); 1292 1320 if (!CHECK_FD_SET(so, NetworkEvents, closefds)) 1321 { 1322 so->fUnderPolling = 0; 1293 1323 CONTINUE(tcp); 1324 } 1294 1325 } 1295 1326 1296 1327 ret = soread(pData, so); 1328 if (slirpVerifyAndFreeSocket(pData, so)) 1329 CONTINUE(tcp); 1297 1330 /* Output it if we read something */ 1298 1331 if (RT_LIKELY(ret > 0)) 1299 1332 TCP_OUTPUT(pData, sototcpcb(so)); 1333 1334 if (slirpVerifyAndFreeSocket(pData, so)) 1335 CONTINUE(tcp); 1300 1336 } 1301 1337 … … 1307 1343 || (so->so_close == 1)) 1308 1344 { 1309 struct socket *pPrevSo = NULL;1310 /**1311 * we need easy way to detection mechanism if socket has been freed or not1312 * before continuing any further diagnostic.1313 */1314 pPrevSo = so->so_prev;1315 AssertPtr(pPrevSo);1316 1345 /* 1317 1346 * drain the socket 1318 1347 */ 1319 for (; pPrevSo->so_next == so ;) 1348 for (; so_next->so_prev == so 1349 && !slirpVerifyAndFreeSocket(pData, so);) 1320 1350 { 1321 1351 ret = soread(pData, so); 1352 if (slirpVerifyAndFreeSocket(pData, so)) 1353 break; 1354 1322 1355 if (ret > 0) 1323 1356 TCP_OUTPUT(pData, sototcpcb(so)); 1324 else if ( pPrevSo->so_next== so)1357 else if (so_next->so_prev == so) 1325 1358 { 1326 1359 Log2(("%R[natsock] errno %d (%s)\n", so, errno, strerror(errno))); … … 1328 1361 } 1329 1362 } 1330 if (pPrevSo->so_next == so) 1363 1364 /* if socket freed ''so'' is PHANTOM and next socket isn't points on it */ 1365 if (so_next->so_prev == so) 1331 1366 { 1332 1367 /* mark the socket for termination _after_ it was drained */ … … 1339 1374 #endif 1340 1375 } 1376 if (so_next->so_prev == so) 1377 so->fUnderPolling = 0; 1341 1378 CONTINUE(tcp); 1342 1379 } … … 1352 1389 { 1353 1390 if(!slirpConnectOrWrite(pData, so, false)) 1391 { 1392 if (!slirpVerifyAndFreeSocket(pData, so)) 1393 so->fUnderPolling = 0; 1354 1394 CONTINUE(tcp); 1395 } 1355 1396 } 1356 1397 … … 1403 1444 } /* SS_ISFCONNECTING */ 1404 1445 #endif 1446 if (!slirpVerifyAndFreeSocket(pData, so)) 1447 so->fUnderPolling = 0; 1405 1448 LOOP_LABEL(tcp, so, so_next); 1406 1449 } -
trunk/src/VBox/Devices/Network/slirp/socket.c
r40622 r41178 195 195 m_freem(pData, so->so_m); 196 196 #ifndef VBOX_WITH_SLIRP_MT 197 if (so->so_next && so->so_prev) 198 { 199 remque(pData, so); /* crashes if so is not in a queue */ 200 NSOCK_DEC(); 201 } 202 203 RTMemFree(so); 197 /* 198 * We should not remove socket when polling routine do the polling 199 * instead we mark it for deletion. 200 */ 201 if (!so->fUnderPolling) 202 { 203 if (so->so_next && so->so_prev) 204 { 205 remque(pData, so); /* crashes if so is not in a queue */ 206 NSOCK_DEC(); 207 } 208 209 RTMemFree(so); 210 } 211 else 212 so->fShouldBeRemoved = 1; 204 213 #else 205 214 so->so_deleted = 1; -
trunk/src/VBox/Devices/Network/slirp/socket.h
r40621 r41178 112 112 int so_cCloneCounter; /* number of clones */ 113 113 #endif 114 /** These flags (''fUnderPolling'' and ''fShouldBeRemoved'') introduced to 115 * to let polling routine gain control over freeing socket whatever level of 116 * TCP/IP initiated socket releasing. 117 * So polling routine when start processing socket alter it's state to 118 * ''fUnderPolling'' to 1, and clean (set to 0) when it finish. 119 * When polling routine calls functions it should be ensure on return, 120 * whether ''fShouldBeRemoved'' set or not, and depending on state call 121 * ''sofree'' or continue socket processing. 122 * On ''fShouldBeRemoved'' equal to 1, polling routine should call ''sofree'', 123 * clearing ''fUnderPolling'' to do real freeng of the socket and removing from 124 * the queue. 125 * @todo: perhaps, to simplefy the things we need some helper function. 126 * @note: it's used like a bool, I use 'int' to avoid compiler warnings 127 * appearing if [-Wc++-compat] used. 128 */ 129 int fUnderPolling; 130 /** This flag used by ''sofree'' function in following manner 131 * 132 * fUnderPolling = 1, then we don't remove socket from the queue, just 133 * alter value ''fShouldBeRemoved'' to 1, else we do removal. 134 */ 135 int fShouldBeRemoved; 114 136 }; 115 137
Note:
See TracChangeset
for help on using the changeset viewer.