AutoLock.cpp revision 4dc53fa82b7910b5b8623dc74f8c2906f9d9855b
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * Automatic locks, implementation
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * Copyright (C) 2006-2012 Oracle Corporation
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * This file is part of VirtualBox Open Source Edition (OSE), as
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * available from http://www.virtualbox.org. This file is free software;
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * you can redistribute it and/or modify it under the terms of the GNU
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * General Public License (GPL) as published by the Free Software
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * Foundation, in version 2 as it comes in the "COPYING" file of the
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest# include <iprt/asm.h> // for ASMReturnAddress
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest////////////////////////////////////////////////////////////////////////////////
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest// RuntimeLockClass
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest////////////////////////////////////////////////////////////////////////////////
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forresttypedef std::map<VBoxLockingClass, RTLOCKVALCLASS> LockValidationClassesMap;
c9beca4b724f480698592be6f34e05fec7a03d23Andrew ForrestLockValidationClassesMap g_mapLockValidationClasses;
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * Called from initterm.cpp on process initialization (on the main thread)
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest * to give us a chance to initialize lock validation runtime data.
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest { LOCKCLASS_VIRTUALBOXOBJECT, "1-VIRTUALBOXOBJECT" },
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest { LOCKCLASS_LISTOFMACHINES, "4-LISTOFMACHINES" },
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest { LOCKCLASS_MACHINEOBJECT, "5-MACHINEOBJECT" },
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest { LOCKCLASS_SNAPSHOTOBJECT, "6-SNAPSHOTOBJECT" },
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest { LOCKCLASS_LISTOFOTHEROBJECTS, "9-LISTOFOTHEROBJECTS" },
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest { LOCKCLASS_PROGRESSLIST, "12-PROGRESSLIST" },
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest for (unsigned i = 0; i < RT_ELEMENTS(aClasses); ++i)
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest true, /*fAutodidact*/
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest // teach the new class that the classes created previously can be held
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest // while the new class is being acquired
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest for (LockValidationClassesMap::iterator it = g_mapLockValidationClasses.begin();
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest vrc = RTLockValidatorClassAddPriorClass(hClass,
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest // and store the new class
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest g_mapLockValidationClasses[aClasses[i].cls] = hClass;
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest/* WriteLockHandle critsect1(LOCKCLASS_VIRTUALBOXOBJECT);
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest WriteLockHandle critsect2(LOCKCLASS_VIRTUALBOXLIST);
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest AutoWriteLock lock1(critsect1 COMMA_LOCKVAL_SRC_POS);
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest AutoWriteLock lock2(critsect2 COMMA_LOCKVAL_SRC_POS);*/
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrestbool AutoLockHoldsLocksInClass(VBoxLockingClass lockClass)
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest return RTLockValidatorHoldsLocksInClass(NIL_RTTHREAD,
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest#else /* !VBOX_WITH_MAIN_LOCK_VALIDATION */
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest return false;
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest#endif /* !VBOX_WITH_MAIN_LOCK_VALIDATION */
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest////////////////////////////////////////////////////////////////////////////////
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest// RWLockHandle
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest////////////////////////////////////////////////////////////////////////////////
c9beca4b724f480698592be6f34e05fec7a03d23Andrew ForrestRWLockHandle::RWLockHandle(VBoxLockingClass lockClass)
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest m->strDescription = com::Utf8StrFmt("r/w %RCv", this);
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest int vrc = RTSemRWCreateEx(&m->sem, 0 /*fFlags*/, g_mapLockValidationClasses[lockClass], RTLOCKVAL_SUB_CLASS_ANY, NULL);
c9beca4b724f480698592be6f34e05fec7a03d23Andrew Forrest int vrc = RTSemRWCreateEx(&m->sem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL);
int vrc = RTSemRWRequestWriteDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS);
int vrc = RTSemRWRequestReadDebug(m->sem, RT_INDEFINITE_WAIT, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS);
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),
const char *pcszFile;
unsigned uLine;
const char *pcszFunction;
++it)
if (pHandle)
++it)
if (pHandle)
if (m->fIsLocked)
m->fIsLocked = true;
m->fIsLocked = false;
if (pHandle)
if (m->fIsLocked)
l.lockRead();
l.unlockRead();
l.lockWrite();
l.unlockWrite();
acquire();
cleanup();
if (aHandle)
if (fWasLocked)
if (pl1)
if (pl2)
acquire();
acquire();
if (pl1)
if (pl2)
if (pl3)
acquire();
acquire();
if (pl1)
if (pl2)
if (pl3)
if (pl4)
acquire();
acquire();