Changeset 38709 in vbox for trunk/src/VBox
- Timestamp:
- Sep 9, 2011 4:45:50 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r38697 r38709 88 88 readers(0), 89 89 preLockState(MediumState_NotCreated), 90 queryInfoSem(NIL_RTSEM EVENTMULTI),90 queryInfoSem(NIL_RTSEMRW), 91 91 queryInfoRunning(false), 92 92 type(MediumType_Normal), … … 124 124 MediumState_T preLockState; 125 125 126 RTSEMEVENTMULTI queryInfoSem; 126 /** Special synchronization for operations which must wait for queryInfo() 127 * in another thread to complete. Using a SemRW is not quite ideal, but at 128 * least it is subject to the lock validator, unlike the SemEventMulti 129 * which we had here for many years. Catching possible deadlocks is more 130 * important than a tiny bit of efficiency. */ 131 RTSEMRW queryInfoSem; 127 132 bool queryInfoRunning : 1; 128 133 … … 886 891 AssertRCReturn(vrc, E_FAIL); 887 892 888 vrc = RTSemEventMultiCreate(&m->queryInfoSem); 889 AssertRCReturn(vrc, E_FAIL); 890 vrc = RTSemEventMultiSignal(m->queryInfoSem); 893 vrc = RTSemRWCreate(&m->queryInfoSem); 891 894 AssertRCReturn(vrc, E_FAIL); 892 895 … … 1369 1372 } 1370 1373 1371 RTSemEventMultiSignal(m->queryInfoSem); 1372 RTSemEventMultiDestroy(m->queryInfoSem); 1373 m->queryInfoSem = NIL_RTSEMEVENTMULTI; 1374 RTSemRWDestroy(m->queryInfoSem); 1375 m->queryInfoSem = NIL_RTSEMRW; 1374 1376 1375 1377 unconst(m->pVirtualBox) = NULL; … … 2094 2096 { 2095 2097 alock.leave(); 2096 RTSemEventMultiWait(m->queryInfoSem, RT_INDEFINITE_WAIT); 2098 RTSemRWRequestRead(m->queryInfoSem, RT_INDEFINITE_WAIT); 2099 RTSemRWReleaseRead(m->queryInfoSem); 2097 2100 alock.enter(); 2098 2101 } … … 2200 2203 { 2201 2204 alock.leave(); 2202 RTSemEventMultiWait(m->queryInfoSem, RT_INDEFINITE_WAIT); 2205 RTSemRWRequestRead(m->queryInfoSem, RT_INDEFINITE_WAIT); 2206 RTSemRWReleaseRead(m->queryInfoSem); 2203 2207 alock.enter(); 2204 2208 } … … 5278 5282 || m->state == MediumState_LockedWrite); 5279 5283 5280 alock.leave(); 5281 vrc = RTSemEventMultiWait(m->queryInfoSem, RT_INDEFINITE_WAIT); 5282 alock.enter(); 5283 5284 AssertRC(vrc); 5284 while (m->queryInfoRunning) 5285 { 5286 alock.leave(); 5287 vrc = RTSemRWRequestRead(m->queryInfoSem, RT_INDEFINITE_WAIT); 5288 RTSemRWReleaseRead(m->queryInfoSem); 5289 AssertRC(vrc); 5290 alock.enter(); 5291 } 5285 5292 5286 5293 return S_OK; … … 5335 5342 bool fRepairImageZeroParentUuid = false; 5336 5343 5337 /* leave the lock before a lengthy operation */ 5338 vrc = RTSemEventMultiReset(m->queryInfoSem); 5339 AssertRCReturn(vrc, E_FAIL); 5344 /* leave the object lock before a lengthy operation */ 5340 5345 m->queryInfoRunning = true; 5341 5346 alock.leave(); 5347 /* Note that taking the queryInfoSem after leaving the object lock above 5348 * can lead to short spinning of the loops waiting for queryInfo() to 5349 * complete. This is unavoidable since the other order causes a lock order 5350 * violation: here it would be requesting the object lock (at the beginning 5351 * of the method), then SemRW, and below the other way round. */ 5352 vrc = RTSemRWRequestWrite(m->queryInfoSem, RT_INDEFINITE_WAIT); 5353 AssertRCReturn(vrc, E_FAIL); 5342 5354 5343 5355 try … … 5570 5582 } 5571 5583 5572 /* inform other callers if there are any*/5573 RTSem EventMultiSignal(m->queryInfoSem);5584 /* unblock anyone waiting for the queryInfo results */ 5585 RTSemRWReleaseWrite(m->queryInfoSem); 5574 5586 m->queryInfoRunning = false; 5575 5587
Note:
See TracChangeset
for help on using the changeset viewer.