Changeset 10819 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Jul 22, 2008 5:58:54 PM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r10806 r10819 37 37 #include <iprt/string.h> 38 38 #include <iprt/time.h> 39 #include <iprt/handletable.h> 39 40 40 41 … … 61 62 /** Whether the interface is active or not. */ 62 63 bool fActive; 64 /** Whether someone is currently in the destructor. */ 65 bool volatile fDestroying; 63 66 /** Number of yields done to try make the interface read pending data. 64 67 * We will stop yeilding when this reaches a threshold assuming that the VM is paused or … … 75 78 R3PTRTYPE(PINTNETBUF) pIntBufDefaultR3; 76 79 /** Event semaphore which a receiver thread will sleep on while waiting for data to arrive. */ 77 RTSEMEVENT 80 RTSEMEVENT volatile Event; 78 81 /** Number of threads sleeping on the Event semaphore. */ 79 82 uint32_t cSleepers; … … 81 84 * When this is INTNET_HANDLE_INVALID a sleeper which is waking up 82 85 * should return with the appropriate error condition. */ 83 INTNETIFHANDLE 86 INTNETIFHANDLE volatile hIf; 84 87 /** Pointer to the network this interface is connected to. 85 88 * This is protected by the INTNET::FastMutex. */ … … 160 163 161 164 /** 162 * Handle table entry.163 * @todo move to IPRT.164 */165 typedef union INTNETHTE166 {167 /** Pointer to the object we're a handle for. */168 PINTNETIF pIF;169 /** Index to the next free entry. */170 uintptr_t iNext;171 } INTNETHTE;172 /** Pointer to a handle table entry. */173 typedef INTNETHTE *PINTNETHTE;174 175 176 /**177 * Handle table.178 * @todo move to IPRT (RTHandleTableCreate/Destroy/Add/Delete/Lookup).179 */180 typedef struct INTNETHT181 {182 /** Spinlock protecting all access. */183 RTSPINLOCK Spinlock;184 /** Pointer to the handle table. */185 PINTNETHTE paEntries;186 /** The number of allocated handles. */187 uint32_t cAllocated;188 /** The index of the first free handle entry.189 * UINT32_MAX means empty list. */190 uint32_t volatile iHead;191 /** The index of the last free handle entry.192 * UINT32_MAX means empty list. */193 uint32_t volatile iTail;194 } INTNETHT;195 /** Pointer to a handle table. */196 typedef INTNETHT *PINTNETHT;197 198 199 /**200 165 * Internal networking instance. 201 166 */ … … 208 173 PINTNETNETWORK volatile pNetworks; 209 174 /** Handle table for the interfaces. */ 210 INTNETHT IfHandles;175 RTHANDLETABLE hHtIfs; 211 176 } INTNET; 212 177 … … 223 188 224 189 /** 225 * Validates and translates an interface handle to a interface pointer. 226 * 227 * The caller already owns the spinlock, which means this is 228 * for internal use only. 229 * 230 * @returns Pointer to interface. 231 * @returns NULL if the handle is invalid. 232 * @param pHT Pointer to the handle table. 233 * @param hIF The interface handle to validate and translate. 234 * 235 * @internal 236 */ 237 DECLINLINE(PINTNETIF) intnetR0Handle2IFPtrLocked(PINTNETHT pHT, INTNETIFHANDLE hIF) 238 { 239 if (RT_LIKELY((hIF & INTNET_HANDLE_MAGIC) == INTNET_HANDLE_MAGIC)) 240 { 241 const uint32_t i = hIF & INTNET_HANDLE_INDEX_MASK; 242 if (RT_LIKELY( i < pHT->cAllocated 243 && pHT->paEntries[i].iNext >= INTNET_HANDLE_MAX 244 && pHT->paEntries[i].iNext != UINT32_MAX)) 245 return pHT->paEntries[i].pIF; 246 } 247 return NULL; 248 } 249 250 251 /** 252 * Validates and translates an interface handle to a interface pointer. 253 * 254 * @returns Pointer to interface. 255 * @returns NULL if the handle is invalid. 256 * @param pHT Pointer to the handle table. 257 * @param hIF The interface handle to validate and translate. 258 */ 259 DECLINLINE(PINTNETIF) intnetR0Handle2IFPtr(PINTNETHT pHT, INTNETIFHANDLE hIF) 260 { 261 AssertPtr(pHT); 262 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 263 RTSpinlockAcquire(pHT->Spinlock, &Tmp); 264 PINTNETIF pIF = intnetR0Handle2IFPtrLocked(pHT, hIF); 265 RTSpinlockRelease(pHT->Spinlock, &Tmp); 266 267 return pIF; 268 } 269 270 271 /** 272 * Allocates a handle for an interface. 273 * 274 * @returns Handle on success. 275 * @returns Invalid handle on failure. 276 * @param pIntNet Pointer to the instance data. 277 * @param pIF The interface which we're allocating a handle for. 278 */ 279 static INTNETIFHANDLE intnetR0HandleAllocate(PINTNET pIntNet, PINTNETIF pIF) 280 { 281 Assert(pIF); 282 Assert(pIntNet); 283 unsigned cTries = 10; 284 PINTNETHT pHT = &pIntNet->IfHandles; 285 PINTNETHTE paNew = NULL; 286 287 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 288 RTSpinlockAcquire(pHT->Spinlock, &Tmp); 289 for (;;) 290 { 291 /* 292 * Check the free list. 293 */ 294 uint32_t i = pHT->iHead; 295 if (i != UINT32_MAX) 296 { 297 pHT->iHead = pHT->paEntries[i].iNext; 298 if (pHT->iHead == UINT32_MAX) 299 pHT->iTail = UINT32_MAX; 300 301 pHT->paEntries[i].pIF = pIF; 302 RTSpinlockRelease(pHT->Spinlock, &Tmp); 303 if (paNew) 304 RTMemFree(paNew); 305 return i | INTNET_HANDLE_MAGIC; 306 } 307 308 /* 309 * Leave the spinlock and allocate a new array. 310 */ 311 const unsigned cNew = pHT->cAllocated + 128; 312 RTSpinlockRelease(pHT->Spinlock, &Tmp); 313 if (--cTries <= 0) 314 { 315 AssertMsgFailed(("Giving up!\n")); 316 break; 317 } 318 paNew = (PINTNETHTE)RTMemAlloc(sizeof(*paNew) * cNew); 319 if (!paNew) 320 break; 321 322 /* 323 * Acquire the spinlock and check if someone raced us. 324 */ 325 RTSpinlockAcquire(pHT->Spinlock, &Tmp); 326 if (pHT->cAllocated < cNew) 327 { 328 /* copy the current table. */ 329 memcpy(paNew, pHT->paEntries, pHT->cAllocated * sizeof(*paNew)); 330 331 /* link the new entries into the free chain. */ 332 i = pHT->cAllocated; 333 uint32_t iTail = pHT->iTail; 334 if (iTail == UINT32_MAX) 335 pHT->iHead = iTail = i++; 336 while (i < cNew) 337 { 338 paNew[iTail].iNext = i; 339 iTail = i++; 340 } 341 paNew[iTail].iNext = UINT32_MAX; 342 pHT->iTail = iTail; 343 344 /* update the handle table. */ 345 pHT->cAllocated = cNew; 346 paNew = (PINTNETHTE)ASMAtomicXchgPtr((void * volatile *)&pHT->paEntries, paNew); 347 } 348 } 349 350 if (paNew) 351 RTMemFree(paNew); 352 return INTNET_HANDLE_INVALID; 353 } 354 355 356 /** 357 * Validates and frees a handle. 358 * 359 * @returns Pointer to interface. 360 * @returns NULL if the handle is invalid. 361 * @param pHT Pointer to the handle table. 362 * @param h The handle we're freeing. 363 */ 364 static PINTNETIF intnetR0HandleFree(PINTNETHT pHT, INTNETIFHANDLE h) 365 { 366 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 367 RTSpinlockAcquire(pHT->Spinlock, &Tmp); 368 369 /* 370 * Validate and get it, then insert the handle table entry 371 * at the end of the free list. 372 */ 373 PINTNETIF pIF = intnetR0Handle2IFPtrLocked(pHT, h); 374 if (pIF) 375 { 376 const uint32_t i = h & INTNET_HANDLE_INDEX_MASK; 377 pHT->paEntries[i].iNext = UINT32_MAX; 378 const uint32_t iTail = pHT->iTail; 379 if (iTail != UINT32_MAX) 380 pHT->paEntries[iTail].iNext = i; 381 else 382 pHT->iHead = i; 383 pHT->iTail = i; 384 } 385 386 RTSpinlockRelease(pHT->Spinlock, &Tmp); 387 388 AssertMsg(pIF, ("%d >= %d\n", h & INTNET_HANDLE_INDEX_MASK, pHT->cAllocated)); 389 return pIF; 190 * Retain an interface. 191 * 192 * @returns VBox status code, can assume success in most situations. 193 * @param pIf The interface instance. 194 * @param pSession The current session. 195 */ 196 DECLINLINE(int) intnetR0IfRetain(PINTNETIF pIf, PSUPDRVSESSION pSession) 197 { 198 int rc = SUPR0ObjAddRef(pIf->pvObj, pSession); 199 AssertRCReturn(rc, rc); 200 return VINF_SUCCESS; 201 } 202 203 204 /** 205 * Release an interface previously retained by intnetR0IfRetain or 206 * by handle lookup/freeing. 207 * 208 * @returns VBox status code, can assume success in most situations. 209 * @param pIf The interface instance. 210 * @param pSession The current session. 211 */ 212 DECLINLINE(void) intnetR0IfRelease(PINTNETIF pIf, PSUPDRVSESSION pSession) 213 { 214 int rc = SUPR0ObjRelease(pIf->pvObj, pSession); 215 AssertRC(rc); 216 } 217 218 219 /** 220 * RTHandleCreateEx callback that retains an object in the 221 * handle table before returning it. 222 * 223 * (Avoids racing the freeing of the handle.) 224 * 225 * @returns VBox status code. 226 * @param hHandleTable The handle table (ignored). 227 * @param pvObj The object (INTNETIF). 228 * @param pvCtx The context (SUPDRVSESSION). 229 * @param pvUser The user context (ignored). 230 */ 231 static DECLCALLBACK(int) intnetR0IfRetainHandle(RTHANDLETABLE hHandleTable, void *pvObj, void *pvCtx, void *pvUser) 232 { 233 NOREF(pvUser); 234 NOREF(hHandleTable); 235 PINTNETIF pIf = (PINTNETIF)pvObj; 236 if (pIf->hIf != INTNET_HANDLE_INVALID) /* Don't try retain it if called from intnetR0IfDestruct. */ 237 return intnetR0IfRetain(pIf, (PSUPDRVSESSION)pvCtx); 238 return VINF_SUCCESS; 390 239 } 391 240 … … 991 840 INTNETR0DECL(int) INTNETR0IfSend(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, const void *pvFrame, unsigned cbFrame) 992 841 { 993 // LogFlow(("INTNETR0IfSend: pIntNet=%p hIf=%RX32 pvFrame=%p cbFrame=%u\n", pIntNet, hIf, pvFrame, cbFrame));842 Log5(("INTNETR0IfSend: pIntNet=%p hIf=%RX32 pvFrame=%p cbFrame=%u\n", pIntNet, hIf, pvFrame, cbFrame)); 994 843 995 844 /* 996 845 * Validate input and translate the handle. 997 846 */ 998 /** @todo add an exctra reference to the interface! */999 847 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 1000 PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);1001 if (!pIf)1002 return VERR_INVALID_HANDLE;1003 848 if (pvFrame && cbFrame) 1004 849 { … … 1010 855 ASMProbeReadBuffer(pvFrame, cbFrame); 1011 856 } 857 PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 858 if (!pIf) 859 return VERR_INVALID_HANDLE; 1012 860 1013 861 /* … … 1021 869 int rc = RTSemFastMutexRequest(pNetwork->FastMutex); 1022 870 if (RT_FAILURE(rc)) 871 { 872 intnetR0IfRelease(pIf, pSession); 1023 873 return rc; 874 } 1024 875 PINTNETTRUNKIF pTrunkIf = intnetR0TrunkIfRetain(pNetwork->pTrunkIF); 1025 876 if (pTrunkIf) … … 1030 881 { 1031 882 intnetR0TrunkIfRelease(pTrunkIf); 883 intnetR0IfRelease(pIf, pSession); 1032 884 return VERR_SEM_DESTROYED; 1033 885 } … … 1038 890 intnetR0TrunkIfOutUnlock(pTrunkIf); 1039 891 intnetR0TrunkIfRelease(pTrunkIf); 892 intnetR0IfRelease(pIf, pSession); 1040 893 return rc; 1041 894 } … … 1087 940 } 1088 941 942 intnetR0IfRelease(pIf, pSession); 1089 943 return rc; 1090 944 } … … 1124 978 */ 1125 979 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 1126 PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); 980 AssertPtrReturn(ppRing3Buf, VERR_INVALID_PARAMETER); 981 *ppRing3Buf = 0; 982 PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 1127 983 if (!pIf) 1128 984 return VERR_INVALID_HANDLE; 1129 AssertPtrReturn(ppRing3Buf, VERR_INVALID_PARAMETER);1130 985 1131 986 /* … … 1135 990 */ 1136 991 int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); 1137 if (RT_FAILURE(rc)) 1138 return rc; 1139 1140 *ppRing3Buf = pIf->pIntBufR3; 1141 1142 rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 992 if (RT_SUCCESS(rc)) 993 { 994 *ppRing3Buf = pIf->pIntBufR3; 995 rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 996 } 997 998 intnetR0IfRelease(pIf, pSession); 1143 999 LogFlow(("INTNETR0IfGetRing3Buffer: returns %Rrc *ppRing3Buf=%p\n", rc, *ppRing3Buf)); 1144 1000 return rc; … … 1166 1022 * 1167 1023 * @returns VBox status code. 1168 * @param pIntNet The instance data. 1169 * @param hIf The interface handle. 1170 * @param ppRing0Buf Where to store the address of the ring-3 mapping. 1171 */ 1172 INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PINTNETBUF *ppRing0Buf) 1024 * @param pIntNet The instance data. 1025 * @param hIf The interface handle. 1026 * @param pSession The caller's session. 1027 * @param ppRing0Buf Where to store the address of the ring-3 mapping. 1028 */ 1029 INTNETR0DECL(int) INTNETR0IfGetRing0Buffer(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF *ppRing0Buf) 1173 1030 { 1174 1031 LogFlow(("INTNETR0IfGetRing0Buffer: pIntNet=%p hIf=%RX32 ppRing0Buf=%p\n", pIntNet, hIf, ppRing0Buf)); … … 1180 1037 *ppRing0Buf = NULL; 1181 1038 AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 1182 PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);1039 PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 1183 1040 if (!pIf) 1184 1041 return VERR_INVALID_HANDLE; … … 1189 1046 */ 1190 1047 int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); 1191 if (RT_FAILURE(rc)) 1192 return rc; 1193 1194 *ppRing0Buf = pIf->pIntBuf; 1195 1196 rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 1048 if (RT_SUCCESS(rc)) 1049 { 1050 *ppRing0Buf = pIf->pIntBuf; 1051 1052 rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 1053 } 1054 intnetR0IfRelease(pIf, pSession); 1197 1055 LogFlow(("INTNETR0IfGetRing0Buffer: returns %Rrc *ppRing0Buf=%p\n", rc, *ppRing0Buf)); 1198 1056 return rc; … … 1216 1074 */ 1217 1075 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 1218 PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf); 1076 AssertPtrReturn(paPages, VERR_INVALID_PARAMETER); 1077 AssertPtrReturn((uint8_t *)&paPages[cPages] - 1, VERR_INVALID_PARAMETER); 1078 PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 1219 1079 if (!pIf) 1220 1080 return VERR_INVALID_HANDLE; 1221 AssertPtrReturn(paPages, VERR_INVALID_PARAMETER);1222 AssertPtrReturn((uint8_t *)&paPages[cPages] - 1, VERR_INVALID_PARAMETER);1223 1081 1224 1082 /* … … 1227 1085 */ 1228 1086 int rc = RTSemFastMutexRequest(pIf->pNetwork->FastMutex); 1229 if (RT_FAILURE(rc)) 1230 return rc; 1231 1232 /** @todo make a SUPR0 api for obtaining the array. SUPR0/IPRT is keeping track of everything, there 1233 * is no need for any extra bookkeeping here.. */ 1234 //*ppRing0Buf = pIf->pIntBuf; 1235 1236 //return RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 1237 RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 1087 if (RT_SUCCESS(rc)) 1088 { 1089 /** @todo make a SUPR0 api for obtaining the array. SUPR0/IPRT is keeping track of everything, there 1090 * is no need for any extra bookkeeping here.. */ 1091 1092 rc = RTSemFastMutexRelease(pIf->pNetwork->FastMutex); 1093 } 1094 intnetR0IfRelease(pIf, pSession); 1238 1095 return VERR_NOT_IMPLEMENTED; 1239 1096 } … … 1258 1115 */ 1259 1116 AssertReturn(pIntNet, VERR_INVALID_PARAMETER); 1260 PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);1117 PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 1261 1118 if (!pIf) 1262 1119 { 1263 Log Flow(("INTNETR0IfSetPromiscuousMode: returns VERR_INVALID_HANDLE\n"));1120 Log(("INTNETR0IfSetPromiscuousMode: returns VERR_INVALID_HANDLE\n")); 1264 1121 return VERR_INVALID_HANDLE; 1265 1122 } … … 1268 1125 * Grab the network semaphore and make the change. 1269 1126 */ 1127 int rc; 1270 1128 PINTNETNETWORK pNetwork = pIf->pNetwork; 1271 if (!pNetwork) 1272 return VERR_WRONG_ORDER; 1273 int rc = RTSemFastMutexRequest(pNetwork->FastMutex); 1274 if (RT_FAILURE(rc)) 1275 return rc; 1276 1277 if (pIf->fPromiscuous != fPromiscuous) 1278 { 1279 Log(("INTNETR0IfSetPromiscuousMode: hIf=%RX32: Changed from %d -> %d\n", 1280 hIf, !fPromiscuous, !!fPromiscuous)); 1281 ASMAtomicUoWriteBool(&pIf->fPromiscuous, fPromiscuous); 1282 } 1283 1284 RTSemFastMutexRelease(pNetwork->FastMutex); 1285 return VINF_SUCCESS; 1129 if (pNetwork) 1130 { 1131 rc = RTSemFastMutexRequest(pNetwork->FastMutex); 1132 if (RT_SUCCESS(rc)) 1133 { 1134 if (pIf->fPromiscuous != fPromiscuous) 1135 { 1136 Log(("INTNETR0IfSetPromiscuousMode: hIf=%RX32: Changed from %d -> %d\n", 1137 hIf, !fPromiscuous, !!fPromiscuous)); 1138 ASMAtomicUoWriteBool(&pIf->fPromiscuous, fPromiscuous); 1139 } 1140 1141 rc = RTSemFastMutexRelease(pNetwork->FastMutex); 1142 } 1143 } 1144 else 1145 rc = VERR_WRONG_ORDER; 1146 1147 intnetR0IfRelease(pIf, pSession); 1148 return rc; 1286 1149 } 1287 1150 … … 1409 1272 INTNETR0DECL(int) INTNETR0IfWait(PINTNET pIntNet, INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, uint32_t cMillies) 1410 1273 { 1411 // LogFlow(("INTNETR0IfWait: pIntNet=%p hIf=%RX32 cMillies=%u\n", pIntNet, hIf, cMillies));1274 Log4(("INTNETR0IfWait: pIntNet=%p hIf=%RX32 cMillies=%u\n", pIntNet, hIf, cMillies)); 1412 1275 1413 1276 /* 1414 1277 * Get and validate essential handles. 1415 1278 */ 1416 Assert Return(pIntNet, VERR_INVALID_PARAMETER);1417 PINTNETIF pIf = intnetR0Handle2IFPtr(&pIntNet->IfHandles, hIf);1279 AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 1280 PINTNETIF pIf = (PINTNETIF)RTHandleTableLookupWithCtx(pIntNet->hHtIfs, hIf, pSession); 1418 1281 if (!pIf) 1419 1282 { 1420 Log Flow(("INTNETR0IfWait: returns VERR_INVALID_HANDLE\n"));1283 Log(("INTNETR0IfWait: returns VERR_INVALID_HANDLE\n")); 1421 1284 return VERR_INVALID_HANDLE; 1422 1285 } 1423 1286 const INTNETIFHANDLE hIfSelf = pIf->hIf; 1424 1287 const RTSEMEVENT Event = pIf->Event; 1425 if ( hIfSelf != hIf 1288 if ( hIfSelf != hIf /* paranoia */ 1426 1289 && Event != NIL_RTSEMEVENT) 1427 1290 { 1428 Log Flow(("INTNETR0IfWait: returns VERR_SEM_DESTROYED\n"));1291 Log(("INTNETR0IfWait: returns VERR_SEM_DESTROYED\n")); 1429 1292 return VERR_SEM_DESTROYED; 1430 1293 } … … 1439 1302 /* 1440 1303 * Increment the number of waiters before starting the wait. 1441 * Upon wakeup we must assert reality checking that we're not 1442 * already destroyed or in the process of being destroyed. 1304 * Upon wakeup we must assert reality, checking that we're not 1305 * already destroyed or in the process of being destroyed. This 1306 * code must be aligned with the waiting code in intnetR0IfDestruct. 1443 1307 */ 1444 1308 ASMAtomicIncU32(&pIf->cSleepers); … … 1447 1311 { 1448 1312 ASMAtomicDecU32(&pIf->cSleepers); 1449 if (pIf->hIf != hIf) 1313 if (!pIf->fDestroying) 1314 { 1315 intnetR0IfRelease(pIf, pSession); 1316 if (pIf->hIf != hIf) 1317 rc = VERR_SEM_DESTROYED; 1318 } 1319 else 1450 1320 rc = VERR_SEM_DESTROYED; 1451 1321 } 1452 1322 else 1453 1323 rc = VERR_SEM_DESTROYED; 1454 // LogFlow(("INTNETR0IfWait: returns %Rrc\n", rc));1324 Log4(("INTNETR0IfWait: returns %Rrc\n", rc)); 1455 1325 return rc; 1456 1326 } … … 1486 1356 1487 1357 /* 1488 * Validate , getand free the handle.1358 * Validate and free the handle. 1489 1359 */ 1490 1360 AssertPtrReturn(pIntNet, VERR_INVALID_PARAMETER); 1491 PINTNETIF pIf = intnetR0HandleFree(&pIntNet->IfHandles, hIf);1361 PINTNETIF pIf = (PINTNETIF)RTHandleTableFreeWithCtx(pIntNet->hHtIfs, hIf, pSession); 1492 1362 if (!pIf) 1493 1363 return VERR_INVALID_HANDLE; 1364 1365 /* mark the handle as freed so intnetR0IfDestruct won't free it again. */ 1494 1366 ASMAtomicWriteU32(&pIf->hIf, INTNET_HANDLE_INVALID); 1495 1367 1496 /* 1497 * Release our reference to the interface object. 1498 */ 1499 int rc = SUPR0ObjRelease(pIf->pvObj, pIf->pSession); 1368 1369 /* 1370 * Release the references to the interface object (handle + free lookup). 1371 * But signal the event semaphore first so any waiter holding a reference 1372 * will wake up too (he'll see hIf == invalid and return correctly). 1373 */ 1374 RTSemEventSignal(pIf->Event); 1375 1376 void *pvObj = pIf->pvObj; 1377 intnetR0IfRelease(pIf, pSession); /* (RTHandleTableFreeWithCtx) */ 1378 1379 int rc = SUPR0ObjRelease(pvObj, pSession); 1500 1380 LogFlow(("INTNETR0IfClose: returns %Rrc\n", rc)); 1501 1381 return rc; … … 1536 1416 1537 1417 /* 1538 * Delete the interface handle so the object no longer can be opened. 1418 * Mark the interface as being destroyed so the waiter 1419 * can behave appropriately (theoretical case). 1420 */ 1421 ASMAtomicWriteBool(&pIf->fDestroying, true); 1422 1423 /* 1424 * Delete the interface handle so the object no longer can be used. 1425 * (Can happen if the client didn't close its session.) 1539 1426 */ 1540 1427 INTNETIFHANDLE hIf = ASMAtomicXchgU32(&pIf->hIf, INTNET_HANDLE_INVALID); 1541 1428 if (hIf != INTNET_HANDLE_INVALID) 1542 intnetR0HandleFree(&pIntNet->IfHandles, hIf); 1429 { 1430 void *pvObj2 = RTHandleTableFreeWithCtx(pIntNet->hHtIfs, hIf, pIf->pSession); 1431 AssertMsg(pvObj2 == pIf, ("%p, %p, hIf=%#x pSession=%p\n", pvObj2, pIf, hIf, pIf->pSession)); 1432 } 1543 1433 1544 1434 /* … … 1589 1479 { 1590 1480 RTSEMEVENT Event = pIf->Event; 1591 ASMAtomicXchgSize(&pIf->Event, NIL_RTSEMEVENT);1592 1481 unsigned cMaxWait = 0x1000; 1593 1482 while (pIf->cSleepers && cMaxWait-- > 0) … … 1607 1496 } 1608 1497 } 1498 1609 1499 RTSemEventDestroy(Event); 1500 pIf->Event = NIL_RTSEMEVENT; 1610 1501 } 1611 1502 … … 1677 1568 //pIf->fPromiscuous = false; 1678 1569 //pIf->fActive = false; 1570 //pIf->fDestroying = false; 1679 1571 //pIf->pIntBuf = 0; 1680 1572 //pIf->pIntBufR3 = NIL_RTR3PTR; … … 1688 1580 pIf->pSession = pSession; 1689 1581 //pIf->pvObj = NULL; 1690 int rc = RTSemEventCreate( &pIf->Event);1582 int rc = RTSemEventCreate((PRTSEMEVENT)&pIf->Event); 1691 1583 if (RT_SUCCESS(rc)) 1692 1584 { … … 1735 1627 if (pIf->pvObj) 1736 1628 { 1737 pIf->hIf = intnetR0HandleAllocate(pNetwork->pIntNet, pIf);1738 if ( pIf->hIf != INTNET_HANDLE_INVALID)1629 rc = RTHandleTableAllocWithCtx(pNetwork->pIntNet->hHtIfs, pIf, pSession, (uint32_t *)&pIf->hIf); 1630 if (RT_SUCCESS(rc)) 1739 1631 { 1740 1632 /* auto activation */ /** @todo do this manually in the future, ditto for setting the MAC address. */ … … 1747 1639 return VINF_SUCCESS; 1748 1640 } 1749 rc = VERR_NO_MEMORY;1750 1641 1751 1642 SUPR0ObjRelease(pIf->pvObj, pSession); … … 1754 1645 } 1755 1646 1756 rc = VERR_NO_MEMORY;1757 1647 RTSemFastMutexDestroy(pNetwork->FastMutex); 1758 1648 pNetwork->FastMutex = NIL_RTSEMFASTMUTEX; … … 2547 2437 pIntNet->FastMutex = NIL_RTSEMFASTMUTEX; 2548 2438 } 2549 if (pIntNet->IfHandles.Spinlock != NIL_RTSPINLOCK) 2550 { 2551 RTSpinlockDestroy(pIntNet->IfHandles.Spinlock); 2552 pIntNet->IfHandles.Spinlock = NIL_RTSPINLOCK; 2439 if (pIntNet->hHtIfs != NIL_RTHANDLETABLE) 2440 { 2441 /** @todo does it make sense to have a deleter here? */ 2442 RTHandleTableDestroy(pIntNet->hHtIfs, NULL, NULL); 2443 pIntNet->hHtIfs = NIL_RTHANDLETABLE; 2553 2444 } 2554 2445 … … 2571 2462 { 2572 2463 //pIntNet->pNetworks = NULL; 2573 //pIntNet->IfHandles.paEntries = NULL;2574 //pIntNet->IfHandles.cAllocated = 0;2575 pIntNet->IfHandles.iHead = UINT32_MAX;2576 pIntNet->IfHandles.iTail = UINT32_MAX;2577 2464 2578 2465 rc = RTSemFastMutexCreate(&pIntNet->FastMutex); 2579 2466 if (RT_SUCCESS(rc)) 2580 2467 { 2581 rc = RTSpinlockCreate(&pIntNet->IfHandles.Spinlock); 2468 rc = RTHandleTableCreateEx(&pIntNet->hHtIfs, RTHANDLETABLE_FLAGS_LOCKED | RTHANDLETABLE_FLAGS_CONTEXT, 2469 UINT32_C(0x8ffe0000), 4096, intnetR0IfRetainHandle, NULL); 2582 2470 if (RT_SUCCESS(rc)) 2583 2471 { … … 2586 2474 return VINF_SUCCESS; 2587 2475 } 2476 2588 2477 RTSemFastMutexDestroy(pIntNet->FastMutex); 2589 2478 } -
trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
r10806 r10819 34 34 #undef DECLR0CALLBACKMEMBER 35 35 #define DECLR0CALLBACKMEMBER(type, name, args) DECLR3CALLBACKMEMBER(type, name, args) 36 #include <VBox/types.h> 37 typedef void *MYPSUPDRVSESSION; 38 #define PSUPDRVSESSION MYPSUPDRVSESSION 39 36 40 #include <VBox/intnet.h> 37 41 #include <VBox/sup.h> … … 89 93 uint32_t volatile cRefs; 90 94 } OBJREF, *POBJREF; 95 91 96 92 97 /******************************************************************************* … … 450 455 { 451 456 PINTNETBUF pBuf0; 452 rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf0, &pBuf0);457 rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf0, g_pSession, &pBuf0); 453 458 if (VBOX_FAILURE(rc) || !pBuf0) 454 459 { … … 457 462 } 458 463 PINTNETBUF pBuf1; 459 rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf1, &pBuf1);464 rc = INTNETR0IfGetRing0Buffer(pIntNet, hIf1, g_pSession, &pBuf1); 460 465 if (VBOX_FAILURE(rc)) 461 466 {
Note:
See TracChangeset
for help on using the changeset viewer.