From c9e5503e5e2490c4e7e9e0caa80fcc47a1c6f4df Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 28 Aug 2007 02:25:14 +0000 Subject: [PATCH] Notify*() and Unpublish() acquire the threads lock. So they need to know whether the lock is already being held. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22087 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/condition_variable.h | 25 +++++++++++---------- src/system/kernel/condition_variable.cpp | 16 +++++++------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/headers/private/kernel/condition_variable.h b/headers/private/kernel/condition_variable.h index efc9f70762..1b733b910b 100644 --- a/headers/private/kernel/condition_variable.h +++ b/headers/private/kernel/condition_variable.h @@ -59,11 +59,12 @@ public: protected: void Publish(const void* object, const char* objectType); - void Unpublish(); - void Notify(bool all); + void Unpublish(bool threadsLocked); + void Notify(bool all, bool threadsLocked); private: - void _Notify(bool all, status_t result); + void _Notify(bool all, bool threadsLocked, + status_t result); protected: const void* fObject; @@ -81,9 +82,9 @@ public: inline void Publish(const Type* object, const char* objectType); - inline void Unpublish(); - inline void NotifyOne(); - inline void NotifyAll(); + inline void Unpublish(bool threadsLocked = false); + inline void NotifyOne(bool threadsLocked = false); + inline void NotifyAll(bool threadsLocked = false); }; @@ -108,25 +109,25 @@ ConditionVariable::Publish(const Type* object, const char* objectType) template inline void -ConditionVariable::Unpublish() +ConditionVariable::Unpublish(bool threadsLocked) { - PrivateConditionVariable::Unpublish(); + PrivateConditionVariable::Unpublish(threadsLocked); } template inline void -ConditionVariable::NotifyOne() +ConditionVariable::NotifyOne(bool threadsLocked) { - PrivateConditionVariable::Notify(false); + PrivateConditionVariable::Notify(false, threadsLocked); } template inline void -ConditionVariable::NotifyAll() +ConditionVariable::NotifyAll(bool threadsLocked) { - PrivateConditionVariable::Notify(true); + PrivateConditionVariable::Notify(true, threadsLocked); } diff --git a/src/system/kernel/condition_variable.cpp b/src/system/kernel/condition_variable.cpp index 9ef2b9dc13..831e7bed1e 100644 --- a/src/system/kernel/condition_variable.cpp +++ b/src/system/kernel/condition_variable.cpp @@ -280,7 +280,7 @@ PrivateConditionVariable::Publish(const void* object, const char* objectType) void -PrivateConditionVariable::Unpublish() +PrivateConditionVariable::Unpublish(bool threadsLocked) { ASSERT(fObject != NULL); @@ -300,12 +300,12 @@ PrivateConditionVariable::Unpublish() fObjectType = NULL; if (fEntries) - _Notify(true, B_ENTRY_NOT_FOUND); + _Notify(true, threadsLocked, B_ENTRY_NOT_FOUND); } void -PrivateConditionVariable::Notify(bool all) +PrivateConditionVariable::Notify(bool all, bool threadsLocked) { ASSERT(fObject != NULL); @@ -321,16 +321,17 @@ PrivateConditionVariable::Notify(bool all) #endif if (fEntries) - _Notify(all, B_OK); + _Notify(all, threadsLocked, B_OK); } //! Called with interrupts disabled and the condition variable spinlock held. void -PrivateConditionVariable::_Notify(bool all, status_t result) +PrivateConditionVariable::_Notify(bool all, bool threadsLocked, status_t result) { // dequeue and wake up the blocked threads - GRAB_THREAD_LOCK(); + if (!threadsLocked) + GRAB_THREAD_LOCK(); while (PrivateConditionVariableEntry* entry = fEntries) { fEntries = entry->fVariableNext; @@ -366,7 +367,8 @@ PrivateConditionVariable::_Notify(bool all, status_t result) break; } - RELEASE_THREAD_LOCK(); + if (!threadsLocked) + RELEASE_THREAD_LOCK(); }