VirtualBox

Changeset 25280 in vbox for trunk


Ignore:
Timestamp:
Dec 9, 2009 6:15:54 PM (15 years ago)
Author:
vboxsync
Message:

Main: preparation for deadlock detection: prohibit recursive locking from same AutoLock object (never made sense in the first place), remove dead code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/AutoLock.h

    r25279 r25280  
    319319    AutoLockBase(LockHandle *pHandle)
    320320        : mHandle(pHandle),
    321           mLockLevel(0),
    322           mGlobalLockLevel(0)
     321          m_fIsLocked(false),
     322          m_cUnlockedInLeave(0)
    323323    { }
    324324
    325     LockHandle *mHandle;
    326     uint32_t mLockLevel;
    327     uint32_t mGlobalLockLevel;
     325    LockHandle      *mHandle;
     326    bool            m_fIsLocked;
     327    uint32_t        m_cUnlockedInLeave;   // how many times the handle was unlocked in leave(); otherwise 0
    328328};
    329329
     
    401401    ~AutoWriteLock()
    402402    {
     403        cleanup();
     404    }
     405
     406    void cleanup()
     407    {
    403408        if (mHandle)
    404409        {
    405             if (mGlobalLockLevel)
     410            if (m_cUnlockedInLeave)
    406411            {
    407                 mGlobalLockLevel -= mLockLevel;
    408                 mLockLevel = 0;
    409                 for (; mGlobalLockLevel; --mGlobalLockLevel)
     412                // there was a leave() before the destruction: then restore the
     413                // lock level that might have been set by locks other than our own
     414                if (m_fIsLocked)
     415                    --m_cUnlockedInLeave;       // no lock for our own
     416                m_fIsLocked = false;
     417                for (; m_cUnlockedInLeave; --m_cUnlockedInLeave)
    410418                    mHandle->lockWrite();
     419
     420                    // @todo r=dj is this really desirable behavior? maybe leave/enter should go altogether?
    411421            }
    412422
    413             AssertMsg(mLockLevel <= 1, ("Lock level > 1: %d\n", mLockLevel));
    414             for (; mLockLevel; --mLockLevel)
     423            if (m_fIsLocked)
    415424                mHandle->unlockWrite();
    416425        }
     
    428437        if (mHandle)
    429438        {
     439            AssertMsg(!m_fIsLocked, ("m_fIsLocked is true, attempting to lock twice!"));
    430440            mHandle->lockWrite();
    431             ++mLockLevel;
    432             Assert(mLockLevel != 0 /* overflow? */);
     441            m_fIsLocked = true;
    433442        }
    434443    }
     
    444453        if (mHandle)
    445454        {
    446             AssertReturnVoid(mLockLevel != 0 /* unlock() w/o preceding lock()? */);
     455            AssertMsg(m_fIsLocked, ("m_fIsLocked is false, cannot release!"));
    447456            mHandle->unlockWrite();
    448             --mLockLevel;
     457            m_fIsLocked = false;
    449458        }
    450459    }
     
    475484        if (mHandle)
    476485        {
    477             AssertReturnVoid(mLockLevel != 0 /* leave() w/o preceding lock()? */);
    478             AssertReturnVoid(mGlobalLockLevel == 0 /* second leave() in a row? */);
    479 
    480             mGlobalLockLevel = mHandle->writeLockLevel();
    481             AssertReturnVoid(mGlobalLockLevel >= mLockLevel /* logic error! */);
    482 
    483             for (uint32_t left = mGlobalLockLevel; left; --left)
     486            AssertMsg(m_fIsLocked, ("m_fIsLocked is false, cannot leave()!"));
     487            AssertMsg(m_cUnlockedInLeave == 0, ("m_cUnlockedInLeave is %d, must be 0! Called leave() twice?", m_cUnlockedInLeave));
     488
     489            m_cUnlockedInLeave = mHandle->writeLockLevel();
     490            AssertMsg(m_cUnlockedInLeave >= 1, ("m_cUnlockedInLeave is %d, must be >=1!", m_cUnlockedInLeave));
     491
     492            for (uint32_t left = m_cUnlockedInLeave;
     493                 left;
     494                 --left)
    484495                mHandle->unlockWrite();
    485496        }
     
    518529        if (mHandle)
    519530        {
    520             AssertReturnVoid(mLockLevel != 0 /* enter() w/o preceding lock()+leave()? */);
    521             AssertReturnVoid(mGlobalLockLevel != 0 /* enter() w/o preceding leave()? */);
    522 
    523             for (; mGlobalLockLevel; --mGlobalLockLevel)
     531            AssertMsg(m_fIsLocked, ("m_fIsLocked is false, cannot enter()!"));
     532            AssertMsg(m_cUnlockedInLeave != 0, ("m_cUnlockedInLeave is 0! enter() without leave()?"));
     533
     534            for (; m_cUnlockedInLeave; --m_cUnlockedInLeave)
    524535                mHandle->lockWrite();
    525536        }
     
    541552        if (mHandle != aHandle)
    542553        {
    543             uint32_t lockLevel = mLockLevel;
    544 
    545             /* perform the destructor part */
     554            bool fWasLocked = m_fIsLocked;
     555
     556            cleanup();
     557
     558            mHandle = aHandle;
     559            m_fIsLocked = fWasLocked;
     560
    546561            if (mHandle)
    547             {
    548                 if (mGlobalLockLevel)
    549                 {
    550                     mGlobalLockLevel -= mLockLevel;
    551                     mLockLevel = 0;
    552                     for (; mGlobalLockLevel; --mGlobalLockLevel)
    553                         mHandle->lockWrite();
    554                 }
    555 
    556                 AssertMsg(mLockLevel <= 1, ("Lock level > 1: %d\n", mLockLevel));
    557                 for (; mLockLevel; --mLockLevel)
    558                     mHandle->unlockWrite();
    559             }
    560 
    561             mHandle = aHandle;
    562             mLockLevel = lockLevel;
    563 
    564             if (mHandle)
    565                 for (; lockLevel; --lockLevel)
     562                if (fWasLocked)
    566563                    mHandle->lockWrite();
    567564        }
     
    697694        if (mHandle)
    698695        {
    699             AssertMsg(mLockLevel <= 1, ("Lock level > 1: %d\n", mLockLevel));
    700             for (; mLockLevel; --mLockLevel)
     696            if (m_fIsLocked)
    701697                mHandle->unlockRead();
    702698        }
     
    719715        if (mHandle)
    720716        {
     717            AssertMsg(!m_fIsLocked, ("m_fIsLocked is true, attempting to lock twice!"));
    721718            mHandle->lockRead();
    722             ++mLockLevel;
    723             Assert(mLockLevel != 0 /* overflow? */);
     719            m_fIsLocked = true;
    724720        }
    725721    }
     
    735731        if (mHandle)
    736732        {
    737             AssertReturnVoid(mLockLevel != 0 /* unlock() w/o preceding lock()? */);
     733            AssertMsg(m_fIsLocked, ("m_fIsLocked is false, cannot release!"));
    738734            mHandle->unlockRead();
    739             --mLockLevel;
     735            m_fIsLocked = false;
    740736        }
    741     }
    742 
    743     /**
    744      * Attaches another handle to this auto lock instance.
    745      *
    746      * The previous object's lock is completely released before the new one is
    747      * acquired. The lock level of the new handle will be the same. This also
    748      * means that if the lock was not acquired at all before #attach(), it will
    749      * not be acquired on the new handle too.
    750      *
    751      * @param aHandle   New handle to attach.
    752      */
    753     void attach(LockHandle *aHandle)
    754     {
    755         /* detect simple self-reattachment */
    756         if (mHandle != aHandle)
    757         {
    758             uint32_t lockLevel = mLockLevel;
    759             if (mHandle)
    760                 for (; mLockLevel; --mLockLevel)
    761                     mHandle->unlockRead();
    762             mHandle = aHandle;
    763             mLockLevel = lockLevel;
    764             if (mHandle)
    765                 for (; lockLevel; --lockLevel)
    766                     mHandle->lockRead();
    767         }
    768     }
    769 
    770     /** @see attach (LockHandle *) */
    771     void attach(LockHandle &aHandle)
    772     {
    773         attach(&aHandle);
    774     }
    775 
    776     /** @see attach (LockHandle *) */
    777     void attach(const Lockable &aLockable)
    778     {
    779         attach(aLockable.lockHandle());
    780     }
    781 
    782     /** @see attach (LockHandle *) */
    783     void attach(const Lockable *aLockable)
    784     {
    785         attach(aLockable ? aLockable->lockHandle() : NULL);
    786737    }
    787738
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