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:
@@ -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
|
int
|
||||||
sigsuspend(const sigset_t *mask)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user