From 5ee1f125e59267d8dce4c22c7d030d0310eebbf3 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 21 Oct 2009 23:44:59 +0000 Subject: [PATCH] Make use of the wait status field so it can be provided in Notify() and then read out in the ConditionVariableEntry::WaitStatus(). That way you can notify with a specific status that can be read out on the other end. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33718 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/condition_variable.h | 23 +++++++++++++-------- src/system/kernel/condition_variable.cpp | 16 +++++++++----- 2 files changed, 25 insertions(+), 14 deletions(-) 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()) {