Implemented sigsuspend() - not tested, though.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14459 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-10-20 18:09:50 +00:00
parent e4d36dd1f4
commit 7d9e0897ed
+34 -1
View File
@@ -509,10 +509,43 @@ set_alarm(bigtime_t time, uint32 mode)
}
/** Replace the current signal block mask and wait for any event to happen.
* Before returning, the original signal block mask is reinstantiated.
*/
int
sigsuspend(const sigset_t *mask)
{
return B_OK;
struct thread *thread = thread_get_current_thread();
sigset_t oldMask = atomic_get(&thread->sig_block_mask);
cpu_status state;
// set the new block mask and suspend ourselves - we cannot use
// SIGSTOP for this, as signals are only handled upon kernel exit
atomic_set(&thread->sig_block_mask, *mask);
while (true) {
thread->next_state = B_THREAD_SUSPENDED;
state = disable_interrupts();
GRAB_THREAD_LOCK();
scheduler_reschedule();
RELEASE_THREAD_LOCK();
restore_interrupts(state);
if (has_signals_pending(thread))
break;
}
// restore the original block mask
atomic_set(&thread->sig_block_mask, oldMask);
// we're not supposed to actually succeed
// ToDo: could this get us into trouble with SA_RESTART handlers?
return B_INTERRUPTED;
}