kernel/condition_variable: Return the count of unblocked threads from Notify.
No reason not to, and it's needed in user_mutex to avoid a very rare potential race, anyway.
This commit is contained in:
parent
2cc89328fa
commit
aca21731ff
|
@ -58,11 +58,11 @@ public:
|
|||
const char* objectType);
|
||||
void Unpublish();
|
||||
|
||||
inline void NotifyOne(status_t result = B_OK);
|
||||
inline void NotifyAll(status_t result = B_OK);
|
||||
inline int32 NotifyOne(status_t result = B_OK);
|
||||
inline int32 NotifyAll(status_t result = B_OK);
|
||||
|
||||
static void NotifyOne(const void* object, status_t result);
|
||||
static void NotifyAll(const void* object, status_t result);
|
||||
static int32 NotifyOne(const void* object, status_t result);
|
||||
static int32 NotifyAll(const void* object, status_t result);
|
||||
|
||||
void Add(ConditionVariableEntry* entry);
|
||||
int32 EntriesCount() { return atomic_get(&fEntriesCount); }
|
||||
|
@ -79,9 +79,9 @@ public:
|
|||
void Dump() const;
|
||||
|
||||
private:
|
||||
static void _Notify(const void* object, bool all, status_t result);
|
||||
void _Notify(bool all, status_t result);
|
||||
void _NotifyLocked(bool all, status_t result);
|
||||
static int32 _Notify(const void* object, bool all, status_t result);
|
||||
int32 _Notify(bool all, status_t result);
|
||||
int32 _NotifyLocked(bool all, status_t result);
|
||||
|
||||
protected:
|
||||
typedef DoublyLinkedList<ConditionVariableEntry> EntryList;
|
||||
|
@ -102,17 +102,17 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
inline void
|
||||
inline int32
|
||||
ConditionVariable::NotifyOne(status_t result)
|
||||
{
|
||||
_Notify(false, result);
|
||||
return _Notify(false, result);
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
inline int32
|
||||
ConditionVariable::NotifyAll(status_t result)
|
||||
{
|
||||
_Notify(true, result);
|
||||
return _Notify(true, result);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -324,56 +324,58 @@ ConditionVariable::Wait(recursive_lock* lock, uint32 flags, bigtime_t timeout)
|
|||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
/*static*/ int32
|
||||
ConditionVariable::NotifyOne(const void* object, status_t result)
|
||||
{
|
||||
_Notify(object, false, result);
|
||||
return _Notify(object, false, result);
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
/*static*/ int32
|
||||
ConditionVariable::NotifyAll(const void* object, status_t result)
|
||||
{
|
||||
_Notify(object, true, result);
|
||||
return _Notify(object, true, result);
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
/*static*/ int32
|
||||
ConditionVariable::_Notify(const void* object, bool all, status_t result)
|
||||
{
|
||||
InterruptsLocker ints;
|
||||
ReadSpinLocker hashLocker(sConditionVariableHashLock);
|
||||
ConditionVariable* variable = sConditionVariableHash.Lookup(object);
|
||||
if (variable == NULL)
|
||||
return;
|
||||
return 0;
|
||||
SpinLocker variableLocker(variable->fLock);
|
||||
hashLocker.Unlock();
|
||||
|
||||
variable->_NotifyLocked(all, result);
|
||||
return variable->_NotifyLocked(all, result);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
int32
|
||||
ConditionVariable::_Notify(bool all, status_t result)
|
||||
{
|
||||
InterruptsSpinLocker _(fLock);
|
||||
|
||||
if (!fEntries.IsEmpty()) {
|
||||
if (result > B_OK) {
|
||||
panic("tried to notify with invalid result %" B_PRId32 "\n", result);
|
||||
result = B_ERROR;
|
||||
}
|
||||
|
||||
_NotifyLocked(all, result);
|
||||
return _NotifyLocked(all, result);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Called with interrupts disabled and the condition variable's spinlock held.
|
||||
*/
|
||||
void
|
||||
int32
|
||||
ConditionVariable::_NotifyLocked(bool all, status_t result)
|
||||
{
|
||||
int32 notified = 0;
|
||||
|
||||
// Dequeue and wake up the blocked threads.
|
||||
while (ConditionVariableEntry* entry = fEntries.RemoveHead()) {
|
||||
Thread* thread = atomic_pointer_get_and_set(&entry->fThread, (Thread*)NULL);
|
||||
|
@ -417,9 +419,12 @@ ConditionVariable::_NotifyLocked(bool all, status_t result)
|
|||
thread_unblock_locked(thread, result);
|
||||
}
|
||||
|
||||
notified++;
|
||||
if (!all)
|
||||
break;
|
||||
}
|
||||
|
||||
return notified;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue