Changeset 4971 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Sep 21, 2007 10:19:12 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 24737
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDRV.h
r4833 r4971 516 516 /** Pointer to the next in the global list. */ 517 517 struct SUPDRVOBJ * volatile pNext; 518 /** Pointer to the object destructor. */ 518 /** Pointer to the object destructor. 519 * This may be set to NULL if the image containing the destructor get unloaded. */ 519 520 PFNSUPDRVDESTRUCTOR pfnDestructor; 520 521 /** User argument 1. */ … … 612 613 { 613 614 /** Spinlock to serialize the initialization, 614 * usage counting and destruction of the IDT entry override . */615 * usage counting and destruction of the IDT entry override and objects. */ 615 616 RTSPINLOCK Spinlock; 616 617 … … 622 623 #endif 623 624 624 /** List of registered objects. */625 /** List of registered objects. Protected by the spinlock. */ 625 626 PSUPDRVOBJ volatile pObjs; 626 627 /** List of free object usage records. */ -
trunk/src/VBox/HostDrivers/Support/SUPDRVShared.c
r4965 r4971 88 88 { "SUPR0ContAlloc", (void *)SUPR0ContAlloc }, 89 89 { "SUPR0ContFree", (void *)SUPR0ContFree }, 90 { "SUPR0LowAlloc", (void *)SUPR0LowAlloc }, 91 { "SUPR0LowFree", (void *)SUPR0LowFree }, 90 92 { "SUPR0MemAlloc", (void *)SUPR0MemAlloc }, 91 93 { "SUPR0MemGetPhys", (void *)SUPR0MemGetPhys }, … … 429 431 RTSpinlockRelease(pDevExt->Spinlock, &SpinlockTmp); 430 432 431 pObj->pfnDestructor(pObj, pObj->pvUser1, pObj->pvUser2); 433 if (pObj->pfnDestructor) 434 pObj->pfnDestructor(pObj, pObj->pvUser1, pObj->pvUser2); 432 435 RTMemFree(pObj); 433 436 } … … 1315 1318 { 1316 1319 pObj->u32Magic++; 1317 pObj->pfnDestructor(pObj, pObj->pvUser1, pObj->pvUser2); 1320 if (pObj->pfnDestructor) 1321 pObj->pfnDestructor(pObj, pObj->pvUser1, pObj->pvUser2); 1318 1322 RTMemFree(pObj); 1319 1323 } … … 3127 3131 static int supdrvIOCtl_LdrFree(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPLDRFREE pReq) 3128 3132 { 3133 int rc; 3129 3134 PSUPDRVLDRUSAGE pUsagePrev; 3130 3135 PSUPDRVLDRUSAGE pUsage; … … 3153 3158 * Check if we can remove anything. 3154 3159 */ 3160 rc = VINF_SUCCESS; 3155 3161 pImage = pUsage->pImage; 3156 3162 if (pImage->cUsage <= 1 || pUsage->cUsage <= 1) 3157 3163 { 3158 /* unlink it */ 3159 if (pUsagePrev) 3160 pUsagePrev->pNext = pUsage->pNext; 3164 /* 3165 * Check if there are any objects with destructors in the image, if 3166 * so leave it for the session cleanup routine so we get a chance to 3167 * clean things up in the right order and not leave them all dangling. 3168 */ 3169 RTSPINLOCKTMP SpinlockTmp = RTSPINLOCKTMP_INITIALIZER; 3170 RTSpinlockAcquire(pDevExt->Spinlock, &SpinlockTmp); 3171 if (pImage->cUsage <= 1) 3172 { 3173 PSUPDRVOBJ pObj; 3174 for (pObj = pDevExt->pObjs; pObj; pObj = pObj->pNext) 3175 if (RT_UNLIKELY((uintptr_t)pObj->pfnDestructor - (uintptr_t)pImage->pvImage < pImage->cbImage)) 3176 { 3177 rc = VERR_SHARING_VIOLATION; /** @todo VERR_DANGLING_OBJECTS */ 3178 break; 3179 } 3180 } 3161 3181 else 3162 pSession->pLdrUsage = pUsage->pNext; 3163 /* free it */ 3164 pUsage->pImage = NULL; 3165 pUsage->pNext = NULL; 3166 RTMemFree(pUsage); 3167 3168 /* 3169 * Derefrence the image. 3170 */ 3171 if (pImage->cUsage <= 1) 3172 supdrvLdrFree(pDevExt, pImage); 3173 else 3174 pImage->cUsage--; 3182 { 3183 PSUPDRVUSAGE pGenUsage; 3184 for (pGenUsage = pSession->pUsage; pGenUsage; pGenUsage = pGenUsage->pNext) 3185 if (RT_UNLIKELY((uintptr_t)pGenUsage->pObj->pfnDestructor - (uintptr_t)pImage->pvImage < pImage->cbImage)) 3186 { 3187 rc = VERR_SHARING_VIOLATION; /** @todo VERR_DANGLING_OBJECTS */ 3188 break; 3189 } 3190 } 3191 RTSpinlockRelease(pDevExt->Spinlock, &SpinlockTmp); 3192 if (rc == VINF_SUCCESS) 3193 { 3194 /* unlink it */ 3195 if (pUsagePrev) 3196 pUsagePrev->pNext = pUsage->pNext; 3197 else 3198 pSession->pLdrUsage = pUsage->pNext; 3199 3200 /* free it */ 3201 pUsage->pImage = NULL; 3202 pUsage->pNext = NULL; 3203 RTMemFree(pUsage); 3204 3205 /* 3206 * Derefrence the image. 3207 */ 3208 if (pImage->cUsage <= 1) 3209 supdrvLdrFree(pDevExt, pImage); 3210 else 3211 pImage->cUsage--; 3212 } 3175 3213 } 3176 3214 else … … 3423 3461 if (pDevExt->pvVMMR0 == pImage->pvImage) 3424 3462 supdrvLdrUnsetR0EP(pDevExt); 3463 3464 /* check for objects with destructors in this image. (Shouldn't happen.) */ 3465 if (pDevExt->pObjs) 3466 { 3467 unsigned cObjs = 0; 3468 PSUPDRVOBJ pObj; 3469 RTSPINLOCKTMP SpinlockTmp = RTSPINLOCKTMP_INITIALIZER; 3470 RTSpinlockAcquire(pDevExt->Spinlock, &SpinlockTmp); 3471 for (pObj = pDevExt->pObjs; pObj; pObj = pObj->pNext) 3472 if (RT_UNLIKELY((uintptr_t)pObj->pfnDestructor - (uintptr_t)pImage->pvImage < pImage->cbImage)) 3473 { 3474 pObj->pfnDestructor = NULL; 3475 cObjs++; 3476 } 3477 RTSpinlockRelease(pDevExt->Spinlock, &SpinlockTmp); 3478 if (cObjs) 3479 OSDBGPRINT(("supdrvLdrFree: Image '%s' has %d dangling objects!\n", pImage->szName, cObjs)); 3480 } 3425 3481 3426 3482 /* call termination function if fully loaded. */
Note:
See TracChangeset
for help on using the changeset viewer.