The write lock of ReadWriteLock can now be held recursively; ie. you can

hold the lock and still call subsequent Lock() and LockWrite() without
the deadlock penalty.
Added another constructor to WriteLocked so that you can also pass NULL
to it (in this case, nothing happens, of course :)).


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11720 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-03-14 01:37:48 +00:00
parent 4e08f1474d
commit 07646c514a
1 changed files with 40 additions and 13 deletions

View File

@ -24,7 +24,9 @@
// speed up locking - only makes sense if USE_BENAPHORE
// is defined, too.
#endif
#ifdef FAST_LOCK
# error implement recursive write locking first
#endif
class Semaphore {
public:
@ -164,13 +166,7 @@ class RecursiveLock {
{
thread_id thread = find_thread(NULL);
if (thread != fOwner) {
#if __MWERKS__ && !USER //--- The R5 PowerPC kernel doesn't have panic()
char blip[255];
sprintf(blip,"RecursiveLock unlocked by %ld, owned by %ld\n", thread, fOwner);
kernel_debugger(blip);
#else
panic("RecursiveLock unlocked by %ld, owned by %ld\n", thread, fOwner);
#endif
panic("RecursiveLock unlocked by %ld, owned by %ld\n", thread, fOwner);
}
if (--fOwnerCount == 0) {
@ -379,22 +375,44 @@ class ReadWriteLock {
status_t Lock()
{
thread_id currentThread = find_thread(NULL);
if (currentThread == fOwner) {
fOwnerCount++;
return B_OK;
}
return acquire_sem(fSemaphore);
}
void Unlock()
{
thread_id currentThread = find_thread(NULL);
if (fOwner == currentThread && --fOwnerCount > 0)
return;
release_sem(fSemaphore);
}
status_t LockWrite()
{
return acquire_sem_etc(fSemaphore, MAX_READERS, 0, 0);
thread_id currentThread = find_thread(NULL);
if (currentThread == fOwner) {
fOwnerCount++;
return B_OK;
}
status_t status = acquire_sem_etc(fSemaphore, MAX_READERS, 0, 0);
if (status >= B_OK) {
fOwner = currentThread;
fOwnerCount = 1;
}
return status;
}
void UnlockWrite()
{
release_sem_etc(fSemaphore, MAX_READERS, 0);
if (--fOwnerCount == 0) {
fOwner = -1;
release_sem_etc(fSemaphore, MAX_READERS, 0);
}
}
private:
@ -402,6 +420,8 @@ class ReadWriteLock {
friend class WriteLocked;
sem_id fSemaphore;
thread_id fOwner;
int32 fOwnerCount;
};
#endif // FAST_LOCK
@ -431,15 +451,22 @@ class WriteLocked {
public:
WriteLocked(ReadWriteLock &lock)
:
fLock(lock)
fLock(&lock)
{
fStatus = lock.LockWrite();
}
WriteLocked(ReadWriteLock *lock)
:
fLock(lock)
{
fStatus = lock != NULL ? lock->LockWrite() : B_ERROR;
}
~WriteLocked()
{
if (fStatus == B_OK)
fLock.UnlockWrite();
fLock->UnlockWrite();
}
status_t IsLocked()
@ -448,7 +475,7 @@ class WriteLocked {
}
private:
ReadWriteLock &fLock;
ReadWriteLock *fLock;
status_t fStatus;
};