haiku/docs/user/support/Locker.dox
Niels Sascha Reedijk e24e2c66c9 Push some doc changes I have on my harddrive. They don't (all) conform to the guidelines, but I wanted to put these in the repository nonetheless.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20472 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-03-30 13:50:00 +00:00

128 lines
3.0 KiB
Plaintext

/*!
\file Locker.h
\brief Provides locking class BLocker.
*/
/*!
\class BLocker
\ingroup support
\ingroup libbe
\brief Semaphore-type class for thread safety.
The BLocker interface is not merely a wrapper around a semaphore, but it
also has two advantages. First of all, it implements a benaphore.
A benaphore is in some ways more speed efficient,
because before it uses the internal semaphore, it first checks against a
variable that is only operated on with atomic operations. Setting a variable
is a lot more efficient than acquiring a semaphore, thus this type of locking
is much prefered.
It basically works as follows. Whenever you newly created BLocker object
recieves a locking request, it atomically sets the benaphore variable to
\c 1. Then only additional calls from different threads will utilize the
semaphore. You can imagine that in many cases where you protect
of data that \em might be accessed by two or more concurrent threads, but
the chances of it happening being very small, the benaphore benefits the
most from it's speed.
The other feature of BLocker that improves basic semaphore handling is that
it allows for recursive locks. The following piece of code works with a
BLocker, but block inevitably with a semaphore. Let's pretend I call \c Water():
\code
status_t
Flower::Grow(int length)
{
if (fLock->Lock()) {
fLength += lenght;
fLock->Unlock();
return B_OK;
} else {
return B_ERROR;
}
}
status_t
Flower::Water(int amount)
{
if (fLock->Lock()) {
status_t status = Grow(amount * 2);
fLock->Unlock();
return status;
} else {
return B_ERROR;
}
}
\endcode
This code would work because BLocker keeps track of the amount of lock
requests from the same thread. A normal semaphore would block in \c Grow()
because the semaphore would be acquired already. Please do make sure you
pair every Lock() with an Unlock() though, or you'll create a deadlock.
*/
/*!
\fn BLocker::BLocker()
\brief Constructor.
*/
/*!
\fn BLocker::BLocker(const char* name)
\brief Constructor.
*/
/*!
\fn BLocker::BLocker(bool benaphoreStyle)
\brief Constructor.
*/
/*!
\fn BLocker::BLocker(const char* name, bool benaphoreStyle)
\brief Constructor.
*/
/*!
\fn virtual BLocker::~BLocker()
\brief Destructor.
*/
/*!
\fn bool BLocker::Lock(void)
\brief Add a lock request and block on it until we get it.
*/
/*!
\fn status_t BLocker::LockWithTimeout(bigtime_t timeout)
\brief Add a lock request and block until we get it with a maximum time.
*/
/*!
\fn void BLocker::Unlock(void)
\brief Give up the lock count.
*/
/*!
\fn thread_id BLocker::LockingThread(void) const
\brief Return the \c thread_id of the thread that's currently holding the lock.
*/
/*!
\fn bool BLocker::IsLocked(void) const
\brief Check if your lock succeeded.
*/
/*!
\fn int32 BLocker::CountLocks(void) const
\brief Return the number of recursive locks that are currently held.
*/
/*!
\fn nt32 BLocker::CountLockRequests(void) const
\brief Return the number of pending lock requests.
*/
/*!
\fn sem_id BLocker::Sem(void) const
\brief Return the sem_id of the semaphore this object holds.
*/