VirtualBox

Changeset 38709 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 9, 2011 4:45:50 PM (13 years ago)
Author:
vboxsync
Message:

Main/Medium: replace the event semaphore used to wait for queryInfo by a RW semaphore

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r38697 r38709  
    8888          readers(0),
    8989          preLockState(MediumState_NotCreated),
    90           queryInfoSem(NIL_RTSEMEVENTMULTI),
     90          queryInfoSem(NIL_RTSEMRW),
    9191          queryInfoRunning(false),
    9292          type(MediumType_Normal),
     
    124124    MediumState_T preLockState;
    125125
    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;
    127132    bool queryInfoRunning : 1;
    128133
     
    886891    AssertRCReturn(vrc, E_FAIL);
    887892
    888     vrc = RTSemEventMultiCreate(&m->queryInfoSem);
    889     AssertRCReturn(vrc, E_FAIL);
    890     vrc = RTSemEventMultiSignal(m->queryInfoSem);
     893    vrc = RTSemRWCreate(&m->queryInfoSem);
    891894    AssertRCReturn(vrc, E_FAIL);
    892895
     
    13691372    }
    13701373
    1371     RTSemEventMultiSignal(m->queryInfoSem);
    1372     RTSemEventMultiDestroy(m->queryInfoSem);
    1373     m->queryInfoSem = NIL_RTSEMEVENTMULTI;
     1374    RTSemRWDestroy(m->queryInfoSem);
     1375    m->queryInfoSem = NIL_RTSEMRW;
    13741376
    13751377    unconst(m->pVirtualBox) = NULL;
     
    20942096    {
    20952097        alock.leave();
    2096         RTSemEventMultiWait(m->queryInfoSem, RT_INDEFINITE_WAIT);
     2098        RTSemRWRequestRead(m->queryInfoSem, RT_INDEFINITE_WAIT);
     2099        RTSemRWReleaseRead(m->queryInfoSem);
    20972100        alock.enter();
    20982101    }
     
    22002203    {
    22012204        alock.leave();
    2202         RTSemEventMultiWait(m->queryInfoSem, RT_INDEFINITE_WAIT);
     2205        RTSemRWRequestRead(m->queryInfoSem, RT_INDEFINITE_WAIT);
     2206        RTSemRWReleaseRead(m->queryInfoSem);
    22032207        alock.enter();
    22042208    }
     
    52785282               || m->state == MediumState_LockedWrite);
    52795283
    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        }
    52855292
    52865293        return S_OK;
     
    53355342    bool fRepairImageZeroParentUuid = false;
    53365343
    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 */
    53405345    m->queryInfoRunning = true;
    53415346    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);
    53425354
    53435355    try
     
    55705582    }
    55715583
    5572     /* inform other callers if there are any */
    5573     RTSemEventMultiSignal(m->queryInfoSem);
     5584    /* unblock anyone waiting for the queryInfo results */
     5585    RTSemRWReleaseWrite(m->queryInfoSem);
    55745586    m->queryInfoRunning = false;
    55755587
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette