Wait() returns a status_t now, which can be B_OK (condition variable
exists and thread was notified), B_ENTRY_NOT_FOUND (condition variable not found or Unpublish()ed while waiting), or B_INTERRUPTED (interrupted by a signal). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22083 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4f6fa362cf
commit
4ed7917682
@ -29,8 +29,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool Add(const void* object,
|
bool Add(const void* object,
|
||||||
PrivateConditionVariableEntry* threadNext);
|
PrivateConditionVariableEntry* threadNext);
|
||||||
void Wait(uint32 flags);
|
status_t Wait(uint32 flags);
|
||||||
void Wait(const void* object, uint32 flags);
|
status_t Wait(const void* object, uint32 flags);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _Remove();
|
void _Remove();
|
||||||
@ -40,6 +40,7 @@ protected:
|
|||||||
PrivateConditionVariable* fVariable;
|
PrivateConditionVariable* fVariable;
|
||||||
struct thread* fThread;
|
struct thread* fThread;
|
||||||
uint32 fFlags;
|
uint32 fFlags;
|
||||||
|
status_t fResult;
|
||||||
|
|
||||||
PrivateConditionVariableEntry* fThreadPrevious;
|
PrivateConditionVariableEntry* fThreadPrevious;
|
||||||
PrivateConditionVariableEntry* fThreadNext;
|
PrivateConditionVariableEntry* fThreadNext;
|
||||||
@ -62,7 +63,7 @@ protected:
|
|||||||
void Notify(bool all);
|
void Notify(bool all);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _Notify(bool all);
|
void _Notify(bool all, status_t result);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const void* fObject;
|
const void* fObject;
|
||||||
@ -92,11 +93,8 @@ public:
|
|||||||
inline bool Add(const Type* object,
|
inline bool Add(const Type* object,
|
||||||
PrivateConditionVariableEntry* threadNext
|
PrivateConditionVariableEntry* threadNext
|
||||||
= NULL);
|
= NULL);
|
||||||
inline void Wait(uint32 flags = 0);
|
inline status_t Wait(uint32 flags = 0);
|
||||||
inline void Wait(const Type* object, uint32 flags = 0);
|
inline status_t Wait(const Type* object, uint32 flags = 0);
|
||||||
|
|
||||||
private:
|
|
||||||
bool fAdded;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -142,18 +140,18 @@ ConditionVariableEntry<Type>::Add(const Type* object,
|
|||||||
|
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline void
|
inline status_t
|
||||||
ConditionVariableEntry<Type>::Wait(uint32 flags)
|
ConditionVariableEntry<Type>::Wait(uint32 flags)
|
||||||
{
|
{
|
||||||
PrivateConditionVariableEntry::Wait(flags);
|
return PrivateConditionVariableEntry::Wait(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline void
|
inline status_t
|
||||||
ConditionVariableEntry<Type>::Wait(const Type* object, uint32 flags)
|
ConditionVariableEntry<Type>::Wait(const Type* object, uint32 flags)
|
||||||
{
|
{
|
||||||
PrivateConditionVariableEntry::Wait(object, flags);
|
return PrivateConditionVariableEntry::Wait(object, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ PrivateConditionVariableEntry::Add(const void* object,
|
|||||||
|
|
||||||
fThread = thread_get_current_thread();
|
fThread = thread_get_current_thread();
|
||||||
fFlags = 0;
|
fFlags = 0;
|
||||||
|
fResult = B_OK;
|
||||||
|
|
||||||
InterruptsLocker _;
|
InterruptsLocker _;
|
||||||
SpinLocker locker(sConditionVariablesLock);
|
SpinLocker locker(sConditionVariablesLock);
|
||||||
@ -114,19 +115,20 @@ PrivateConditionVariableEntry::Add(const void* object,
|
|||||||
if (fVariable) {
|
if (fVariable) {
|
||||||
fVariableNext = fVariable->fEntries;
|
fVariableNext = fVariable->fEntries;
|
||||||
fVariable->fEntries = this;
|
fVariable->fEntries = this;
|
||||||
}
|
} else
|
||||||
|
fResult = B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
return (fVariable != NULL);
|
return (fVariable != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
PrivateConditionVariableEntry::Wait(uint32 flags)
|
PrivateConditionVariableEntry::Wait(uint32 flags)
|
||||||
{
|
{
|
||||||
if (!are_interrupts_enabled()) {
|
if (!are_interrupts_enabled()) {
|
||||||
panic("wait_for_condition_variable_entry() called with interrupts "
|
panic("wait_for_condition_variable_entry() called with interrupts "
|
||||||
"disabled");
|
"disabled");
|
||||||
return;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
InterruptsLocker _;
|
InterruptsLocker _;
|
||||||
@ -142,7 +144,7 @@ PrivateConditionVariableEntry::Wait(uint32 flags)
|
|||||||
PrivateConditionVariableEntry* entry = firstEntry;
|
PrivateConditionVariableEntry* entry = firstEntry;
|
||||||
while (entry) {
|
while (entry) {
|
||||||
if (entry->fVariable == NULL)
|
if (entry->fVariable == NULL)
|
||||||
return;
|
return entry->fResult;
|
||||||
|
|
||||||
entry->fFlags = flags;
|
entry->fFlags = flags;
|
||||||
|
|
||||||
@ -159,14 +161,17 @@ PrivateConditionVariableEntry::Wait(uint32 flags)
|
|||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
scheduler_reschedule();
|
scheduler_reschedule();
|
||||||
RELEASE_THREAD_LOCK();
|
RELEASE_THREAD_LOCK();
|
||||||
|
|
||||||
|
return firstEntry->fResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
PrivateConditionVariableEntry::Wait(const void* object, uint32 flags)
|
PrivateConditionVariableEntry::Wait(const void* object, uint32 flags)
|
||||||
{
|
{
|
||||||
if (Add(object, NULL))
|
if (Add(object, NULL))
|
||||||
Wait(flags);
|
return Wait(flags);
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -207,8 +212,9 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32 Flags() const { return fEntry.fFlags; }
|
inline uint32 Flags() const { return fEntry.fFlags; }
|
||||||
inline void Remove() const { fEntry._Remove(); }
|
inline void Remove() const { fEntry._Remove(); }
|
||||||
|
inline void SetResult(status_t result) { fEntry.fResult = result; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrivateConditionVariableEntry& fEntry;
|
PrivateConditionVariableEntry& fEntry;
|
||||||
@ -294,7 +300,7 @@ PrivateConditionVariable::Unpublish()
|
|||||||
fObjectType = NULL;
|
fObjectType = NULL;
|
||||||
|
|
||||||
if (fEntries)
|
if (fEntries)
|
||||||
_Notify(true);
|
_Notify(true, B_ENTRY_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -315,13 +321,13 @@ PrivateConditionVariable::Notify(bool all)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fEntries)
|
if (fEntries)
|
||||||
_Notify(all);
|
_Notify(all, B_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Called with interrupts disabled and the condition variable spinlock held.
|
//! Called with interrupts disabled and the condition variable spinlock held.
|
||||||
void
|
void
|
||||||
PrivateConditionVariable::_Notify(bool all)
|
PrivateConditionVariable::_Notify(bool all, status_t result)
|
||||||
{
|
{
|
||||||
// dequeue and wake up the blocked threads
|
// dequeue and wake up the blocked threads
|
||||||
GRAB_THREAD_LOCK();
|
GRAB_THREAD_LOCK();
|
||||||
@ -330,6 +336,9 @@ PrivateConditionVariable::_Notify(bool all)
|
|||||||
fEntries = entry->fVariableNext;
|
fEntries = entry->fVariableNext;
|
||||||
struct thread* thread = entry->fThread;
|
struct thread* thread = entry->fThread;
|
||||||
|
|
||||||
|
if (thread->condition_variable_entry != NULL)
|
||||||
|
thread->condition_variable_entry->fResult = result;
|
||||||
|
|
||||||
entry->fVariableNext = NULL;
|
entry->fVariableNext = NULL;
|
||||||
entry->fVariable = NULL;
|
entry->fVariable = NULL;
|
||||||
|
|
||||||
@ -401,6 +410,8 @@ condition_variable_interrupt_thread(struct thread* thread)
|
|||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrivateConditionVariableEntry::Private(*entry).SetResult(B_INTERRUPTED);
|
||||||
|
|
||||||
// remove all of the thread's entries from their variables
|
// remove all of the thread's entries from their variables
|
||||||
while (entry) {
|
while (entry) {
|
||||||
PrivateConditionVariableEntry::Private(*entry).Remove();
|
PrivateConditionVariableEntry::Private(*entry).Remove();
|
||||||
|
Loading…
Reference in New Issue
Block a user