diff --git a/headers/private/kernel/condition_variable.h b/headers/private/kernel/condition_variable.h index 5f1a83f1e8..0f13257a12 100644 --- a/headers/private/kernel/condition_variable.h +++ b/headers/private/kernel/condition_variable.h @@ -32,7 +32,9 @@ public: status_t Wait(const void* object, uint32 flags = 0, bigtime_t timeout = 0); - inline ConditionVariable* Variable() const { return fVariable; } + inline status_t WaitStatus() const { return fWaitStatus; } + + inline ConditionVariable* Variable() const { return fVariable; } private: inline void AddToVariable(ConditionVariable* variable); @@ -56,8 +58,10 @@ public: const char* objectType); void Unpublish(bool threadsLocked = false); - inline void NotifyOne(bool threadsLocked = false); - inline void NotifyAll(bool threadsLocked = false); + inline void NotifyOne(bool threadsLocked = false, + status_t result = B_OK); + inline void NotifyAll(bool threadsLocked = false, + status_t result = B_OK); void Add(ConditionVariableEntry* entry); @@ -72,8 +76,9 @@ public: void Dump() const; private: - void _Notify(bool all, bool threadsLocked); - void _NotifyChecked(bool all, status_t result); + void _Notify(bool all, bool threadsLocked, + status_t result); + void _NotifyLocked(bool all, status_t result); protected: typedef DoublyLinkedList EntryList; @@ -109,16 +114,16 @@ ConditionVariableEntry::~ConditionVariableEntry() inline void -ConditionVariable::NotifyOne(bool threadsLocked) +ConditionVariable::NotifyOne(bool threadsLocked, status_t result) { - _Notify(false, threadsLocked); + _Notify(false, threadsLocked, result); } inline void -ConditionVariable::NotifyAll(bool threadsLocked) +ConditionVariable::NotifyAll(bool threadsLocked, status_t result) { - _Notify(true, threadsLocked); + _Notify(true, threadsLocked, result); } diff --git a/src/system/kernel/condition_variable.cpp b/src/system/kernel/condition_variable.cpp index 4777ad2edd..d27a41124e 100644 --- a/src/system/kernel/condition_variable.cpp +++ b/src/system/kernel/condition_variable.cpp @@ -241,7 +241,7 @@ ConditionVariable::Unpublish(bool threadsLocked) fObjectType = NULL; if (!fEntries.IsEmpty()) - _NotifyChecked(true, B_ENTRY_NOT_FOUND); + _NotifyLocked(true, B_ENTRY_NOT_FOUND); } @@ -293,14 +293,20 @@ ConditionVariable::Dump() const void -ConditionVariable::_Notify(bool all, bool threadsLocked) +ConditionVariable::_Notify(bool all, bool threadsLocked, status_t result) { InterruptsLocker _; SpinLocker threadLocker(threadsLocked ? NULL : &gThreadSpinlock); SpinLocker locker(sConditionVariablesLock); - if (!fEntries.IsEmpty()) - _NotifyChecked(all, B_OK); + if (!fEntries.IsEmpty()) { + if (result > B_OK) { + panic("tried to notify with invalid result %ld\n", result); + result = B_ERROR; + } + + _NotifyLocked(all, result); + } } @@ -308,7 +314,7 @@ ConditionVariable::_Notify(bool all, bool threadsLocked) thread lock held. */ void -ConditionVariable::_NotifyChecked(bool all, status_t result) +ConditionVariable::_NotifyLocked(bool all, status_t result) { // dequeue and wake up the blocked threads while (ConditionVariableEntry* entry = fEntries.RemoveHead()) {