AutoLock.cpp revision cdd02359ba9ceffb2e9bd104a572ad1130091f44
/** @file
*
* AutoLock: smart critical section wrapper
*/
/*
* Copyright (C) 2006-2008 innotek GmbH
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "AutoLock.h"
#include "Logging.h"
namespace util
{
{
mReadLockCount = 0;
mWriteLockLevel = 0;
mWriteLockPending = 0;
}
{
}
bool RWLockHandle::isLockedOnCurrentThread() const
{
return locked;
}
void RWLockHandle::lockWrite()
{
if (mWriteLockThread != RTThreadSelf())
{
{
/* wait until all read locks or another write lock is released */
}
}
++ mWriteLockLevel;
}
void RWLockHandle::unlockWrite()
{
if (mWriteLockLevel != 0)
{
-- mWriteLockLevel;
if (mWriteLockLevel == 0)
{
/* no write locks, let writers go if there are any (top priority),
* otherwise let readers go if there are any */
if (mWriteLockPending != 0)
else if (mReadLockCount != 0)
}
}
}
void RWLockHandle::lockRead()
{
++ mReadLockCount;
bool isWriteLock = mWriteLockLevel != 0;
{
/* read lock nested into the write lock, cause return immediately */
isWriteLock = false;
}
else
{
if (!isWriteLock)
{
/* write locks are top priority, so let them go if they are
* pending */
if (mWriteLockPending != 0)
{
isWriteLock = true;
/* the first postponed reader kicks pending writers */
if (isFirstReadLock)
}
}
/* the first waiting reader resets the semaphore before letting it be
* posted (i.e. before leaving the critical section) */
if (isWriteLock && isFirstReadLock)
}
/* wait until the write lock is released */
if (isWriteLock)
}
void RWLockHandle::unlockRead()
{
if (mReadLockCount != 0)
{
if (mWriteLockLevel != 0)
{
/* read unlock nested into the write lock, just decrease the
* counter */
/* unlockRead() after lockWrite()? */);
if (mWriteLockThread == RTThreadSelf())
-- mReadLockCount;
}
else
{
-- mReadLockCount;
if (mReadLockCount == 0)
{
/* no read locks, let writers go if there are any */
if (mWriteLockPending != 0)
}
}
}
}
{
Assert (mWriteLockLevel != 0);
return mWriteLockLevel;
}
} /* namespace util */