From 7d9e0897ed1cea8c5105687f19540f6eacdda720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 20 Oct 2005 18:09:50 +0000 Subject: [PATCH] Implemented sigsuspend() - not tested, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14459 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/signal.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/signal.c b/src/system/kernel/signal.c index b56411db49..c51265978e 100644 --- a/src/system/kernel/signal.c +++ b/src/system/kernel/signal.c @@ -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; }