AutoLock.cpp revision da3229f1051324ee1137c8907b5a647fd76fe17f
3609dfc9f2733f4dc836c6a6bb3745398f280fcevboxsync * Automatic locks, implementation
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2006-2009 Sun Microsystems, Inc.
3609dfc9f2733f4dc836c6a6bb3745398f280fcevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3609dfc9f2733f4dc836c6a6bb3745398f280fcevboxsync * available from http://www.virtualbox.org. This file is free software;
3609dfc9f2733f4dc836c6a6bb3745398f280fcevboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
289060a0c3cb1d509f2cb01fca060796212376f6vboxsync////////////////////////////////////////////////////////////////////////////////
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync// RuntimeLockClass
3609dfc9f2733f4dc836c6a6bb3745398f280fcevboxsync////////////////////////////////////////////////////////////////////////////////
6420f75ffc86ab6494eb5e95418f0c95e71e8068vboxsynctypedef std::map<VBoxLockingClass, RTLOCKVALCLASS> LockValidationClassesMap;
3609dfc9f2733f4dc836c6a6bb3745398f280fcevboxsyncLockValidationClassesMap g_mapLockValidationClasses;
3609dfc9f2733f4dc836c6a6bb3745398f280fcevboxsync * Called from initterm.cpp on process initialization (on the main thread)
6420f75ffc86ab6494eb5e95418f0c95e71e8068vboxsync * to give us a chance to initialize lock validation runtime data.
436b5c616e019c5e62053657c52d3ab5562ecbbfvboxsync { LOCKCLASS_VIRTUALBOXOBJECT, "1-VIRTUALBOXOBJECT" },
436b5c616e019c5e62053657c52d3ab5562ecbbfvboxsync { LOCKCLASS_USBPROXYSERVICE, "2-USBPROXYSERVICE" },
436b5c616e019c5e62053657c52d3ab5562ecbbfvboxsync { LOCKCLASS_LISTOFSNAPSHOTS, "6-LISTOFSNAPSHOTS" },
436b5c616e019c5e62053657c52d3ab5562ecbbfvboxsync { LOCKCLASS_LISTOFOTHEROBJECTS, "9-LISTOFOTHEROBJECTS" },
436b5c616e019c5e62053657c52d3ab5562ecbbfvboxsync for (unsigned i = 0; i < RT_ELEMENTS(aClasses); ++i)
3609dfc9f2733f4dc836c6a6bb3745398f280fcevboxsync true, /*fAutodidact*/
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync // teach the new class that the classes created previously can be held
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync // while the new class is being acquired
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync for (LockValidationClassesMap::iterator it = g_mapLockValidationClasses.begin();
a9981806c72edadef6cccd253f4747c35677e9a1vboxsync // and store the new class
1d94b54d4bd24729c7383e89aa95518204192b22vboxsync g_mapLockValidationClasses[aClasses[i].cls] = hClass;
289060a0c3cb1d509f2cb01fca060796212376f6vboxsync/* WriteLockHandle critsect1(LOCKCLASS_VIRTUALBOXOBJECT);
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync WriteLockHandle critsect2(LOCKCLASS_VIRTUALBOXLIST);
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync AutoWriteLock lock1(critsect1 COMMA_LOCKVAL_SRC_POS);
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync AutoWriteLock lock2(critsect2 COMMA_LOCKVAL_SRC_POS);*/
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync////////////////////////////////////////////////////////////////////////////////
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync// RWLockHandle
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync////////////////////////////////////////////////////////////////////////////////
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsyncRWLockHandle::RWLockHandle(VBoxLockingClass lockClass)
a9981806c72edadef6cccd253f4747c35677e9a1vboxsync m->strDescription = com::Utf8StrFmt("r/w %RCv", this);
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync int vrc = RTSemRWCreateEx(&m->sem, 0 /*fFlags*/, g_mapLockValidationClasses[lockClass], RTLOCKVAL_SUB_CLASS_ANY, NULL);
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync int vrc = RTSemRWCreateEx(&m->sem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL);
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync/*virtual*/ bool RWLockHandle::isWriteLockOnCurrentThread() const
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync/*virtual*/ void RWLockHandle::lockWrite(LOCKVAL_SRC_POS_DECL)
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync int vrc = RTSemRWRequestWriteDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS);
50fdc90dae026b2086f85b0f028aa63dd6bbe14evboxsync int vrc = RTSemRWRequestWrite(m->sem, RT_INDEFINITE_WAIT);
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync/*virtual*/ void RWLockHandle::lockRead(LOCKVAL_SRC_POS_DECL)
a9981806c72edadef6cccd253f4747c35677e9a1vboxsync int vrc = RTSemRWRequestReadDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS);
611910c4ba57eb6db5c0d508ca7b923efd654aecvboxsync int vrc = RTSemRWRequestRead(m->sem, RT_INDEFINITE_WAIT);
Data()
m = new Data;
int vrc = RTCritSectInitEx(&m->sem, 0/*fFlags*/, g_mapLockValidationClasses[lockClass], RTLOCKVAL_SUB_CLASS_ANY, NULL);
int vrc = RTCritSectInitEx(&m->sem, 0/*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL);
unlockWrite();
, const char *pcszFile_,
unsigned uLine_,
const char *pcszFunction_
: fIsLocked(false),
acUnlockedInLeave[i] = 0;
CountsVector acUnlockedInLeave; // for each lock handle, how many times the handle was unlocked in leave(); otherwise 0
const char *pcszFile;
unsigned uLine;
const char *pcszFunction;
++it)
if (pHandle)
++it)
if (pHandle)
bool fAnyUnlockedInLeave = false;
uint32_t i = 0;
++it)
if (pHandle)
if (m->acUnlockedInLeave[i])
if (m->fIsLocked)
--m->acUnlockedInLeave[i];
fAnyUnlockedInLeave = true;
m->fIsLocked = true;
m->fIsLocked = false;
if (pHandle)
if (m->fIsLocked)
l.lockRead();
l.unlockRead();
l.lockWrite();
l.unlockWrite();
* methods of all other AutoWriteLock/AutoReadLock instances managing the
* AutoWriteLock/AutoReadLock instances managing the same semaphore (if
++it)
if (pHandle)
AssertMsg(m->acUnlockedInLeave[i] == 0, ("m->cUnlockedInLeave[%d] is %d, must be 0! Called leave() twice?", i, m->acUnlockedInLeave[i]));
AssertMsg(m->acUnlockedInLeave[i] >= 1, ("m->cUnlockedInLeave[%d] is %d, must be >=1!", i, m->acUnlockedInLeave[i]));
left;
--left)
uint32_t i = 0;
++it)
if (pHandle)
AssertMsg(m->acUnlockedInLeave[i] != 0, ("m->cUnlockedInLeave[%d] is 0! enter() without leave()?", i));
uint32_t i = 0;
++it)
if (pHandle)
cleanup();
if (aHandle)
if (fWasLocked)
if (pl1)
if (pl2)
acquire();
acquire();
if (pl1)
if (pl2)
if (pl3)
acquire();
acquire();