* Made thread_block_with_timeout_lock() more user-friendly. It allows
passing 0 as timeout flags or B_INFINITE_TIMEOUT as timeout, in which case no timer will be used. * Implemented missing thread_block_with_timeout(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25104 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d5b26be18c
commit
60222c8bac
@ -2109,6 +2109,14 @@ thread_unblock(status_t threadID, status_t status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
thread_block_with_timeout(uint32 timeoutFlags, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
InterruptsSpinLocker _(thread_spinlock);
|
||||||
|
return thread_block_with_timeout_locked(timeoutFlags, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
thread_block_with_timeout_locked(uint32 timeoutFlags, bigtime_t timeout)
|
thread_block_with_timeout_locked(uint32 timeoutFlags, bigtime_t timeout)
|
||||||
{
|
{
|
||||||
@ -2117,24 +2125,29 @@ thread_block_with_timeout_locked(uint32 timeoutFlags, bigtime_t timeout)
|
|||||||
if (thread->wait.status != 1)
|
if (thread->wait.status != 1)
|
||||||
return thread->wait.status;
|
return thread->wait.status;
|
||||||
|
|
||||||
// Timer flags: absolute/relative + "acquire thread lock". The latter
|
bool useTimer = (timeoutFlags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT))
|
||||||
// avoids nasty race conditions and deadlock problems that could otherwise
|
&& timeout != B_INFINITE_TIMEOUT;
|
||||||
// occur between our cancel_timer() and a concurrently executing
|
|
||||||
// thread_block_timeout().
|
|
||||||
uint32 timerFlags = (timeoutFlags & B_RELATIVE_TIMEOUT)
|
|
||||||
? B_ONE_SHOT_RELATIVE_TIMER : B_ONE_SHOT_ABSOLUTE_TIMER;
|
|
||||||
timerFlags |= B_TIMER_ACQUIRE_THREAD_LOCK;
|
|
||||||
|
|
||||||
// install the timer
|
if (useTimer) {
|
||||||
thread->wait.unblock_timer.user_data = thread;
|
// Timer flags: absolute/relative + "acquire thread lock". The latter
|
||||||
add_timer(&thread->wait.unblock_timer, &thread_block_timeout, timeout,
|
// avoids nasty race conditions and deadlock problems that could
|
||||||
timerFlags);
|
// otherwise occur between our cancel_timer() and a concurrently
|
||||||
|
// executing thread_block_timeout().
|
||||||
|
uint32 timerFlags = (timeoutFlags & B_RELATIVE_TIMEOUT)
|
||||||
|
? B_ONE_SHOT_RELATIVE_TIMER : B_ONE_SHOT_ABSOLUTE_TIMER;
|
||||||
|
timerFlags |= B_TIMER_ACQUIRE_THREAD_LOCK;
|
||||||
|
|
||||||
|
// install the timer
|
||||||
|
thread->wait.unblock_timer.user_data = thread;
|
||||||
|
add_timer(&thread->wait.unblock_timer, &thread_block_timeout, timeout,
|
||||||
|
timerFlags);
|
||||||
|
}
|
||||||
|
|
||||||
// block
|
// block
|
||||||
status_t error = thread_block_locked(thread);
|
status_t error = thread_block_locked(thread);
|
||||||
|
|
||||||
// cancel timer, if it didn't fire
|
// cancel timer, if it didn't fire
|
||||||
if (error != B_TIMED_OUT)
|
if (error != B_TIMED_OUT && useTimer)
|
||||||
cancel_timer(&thread->wait.unblock_timer);
|
cancel_timer(&thread->wait.unblock_timer);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
Loading…
Reference in New Issue
Block a user