* 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:
Ingo Weinhold 2008-04-22 19:46:08 +00:00
parent d5b26be18c
commit 60222c8bac

View File

@ -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
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)
return thread->wait.status;
// Timer flags: absolute/relative + "acquire thread lock". The latter
// avoids nasty race conditions and deadlock problems that could 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;
bool useTimer = (timeoutFlags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT))
&& timeout != B_INFINITE_TIMEOUT;
// install the timer
thread->wait.unblock_timer.user_data = thread;
add_timer(&thread->wait.unblock_timer, &thread_block_timeout, timeout,
timerFlags);
if (useTimer) {
// Timer flags: absolute/relative + "acquire thread lock". The latter
// avoids nasty race conditions and deadlock problems that could
// 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
status_t error = thread_block_locked(thread);
// cancel timer, if it didn't fire
if (error != B_TIMED_OUT)
if (error != B_TIMED_OUT && useTimer)
cancel_timer(&thread->wait.unblock_timer);
return error;