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