From 5d56aa9cb2bdbe0a18bafbdbb6eb8cf6a46beb79 Mon Sep 17 00:00:00 2001 From: deischen Date: Fri, 18 Apr 2003 05:04:16 +0000 Subject: Revamp libpthread so that it has a chance of working in an SMP environment. This includes support for multiple KSEs and KSEGs. The ability to create more than 1 KSE via pthread_setconcurrency() is in the works as well as support for PTHREAD_SCOPE_SYSTEM threads. Those should come shortly. There are still some known issues which davidxu and I are working on, but it'll make it easier for us by committing what we have. This library now passes all of the ACE tests that libc_r passes with the exception of one. It also seems to work OK with KDE including konqueror, kwrite, etc. I haven't been able to get mozilla to run due to lack of java plugin, so I'd be interested to see how it works with that. Reviewed by: davidxu --- lib/libpthread/thread/thr_sigmask.c | 76 +++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 24 deletions(-) (limited to 'lib/libpthread/thread/thr_sigmask.c') diff --git a/lib/libpthread/thread/thr_sigmask.c b/lib/libpthread/thread/thr_sigmask.c index f98c421..d9cb839 100644 --- a/lib/libpthread/thread/thr_sigmask.c +++ b/lib/libpthread/thread/thr_sigmask.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "thr_private.h" @@ -44,32 +45,59 @@ __weak_reference(_pthread_sigmask, pthread_sigmask); int _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) { - int i; struct pthread *curthread = _get_curthread(); + int ret; + ret = 0; if (oset != NULL) - bcopy(&curthread->mailbox.tm_context.uc_sigmask, oset, - sizeof(sigset_t)); - if (set == NULL) - return (0); - switch (how) { - case SIG_BLOCK: - for (i = 0; i < _SIG_WORDS; i++) - curthread->mailbox.tm_context.uc_sigmask.__bits[i] |= - set->__bits[i]; - break; - case SIG_UNBLOCK: - for (i = 0; i < _SIG_WORDS; i++) - curthread->mailbox.tm_context.uc_sigmask.__bits[i] &= - ~set->__bits[i]; - break; - case SIG_SETMASK: - bcopy(set, &curthread->mailbox.tm_context.uc_sigmask, - sizeof(sigset_t)); - break; - default: - errno = EINVAL; - return (-1); + /* Return the current mask: */ + *oset = curthread->tmbx.tm_context.uc_sigmask; + + /* Check if a new signal set was provided by the caller: */ + if (set != NULL) { + THR_SCHED_LOCK(curthread, curthread); + + /* Process according to what to do: */ + switch (how) { + /* Block signals: */ + case SIG_BLOCK: + /* Add signals to the existing mask: */ + SIGSETOR(curthread->tmbx.tm_context.uc_sigmask, *set); + break; + + /* Unblock signals: */ + case SIG_UNBLOCK: + /* Clear signals from the existing mask: */ + SIGSETNAND(curthread->tmbx.tm_context.uc_sigmask, *set); + break; + + /* Set the signal process mask: */ + case SIG_SETMASK: + /* Set the new mask: */ + curthread->tmbx.tm_context.uc_sigmask = *set; + break; + + /* Trap invalid actions: */ + default: + /* Return an invalid argument: */ + errno = EINVAL; + ret = -1; + break; + } + + if (ret == 0) { + curthread->sigmask = + curthread->tmbx.tm_context.uc_sigmask; + curthread->sigmask_seqno++; + } + + THR_SCHED_UNLOCK(curthread, curthread); + + /* + * Run down any pending signals: + */ + if (ret == 0) + _thr_sig_check_pending(curthread); } - return (0); + return (ret); } -- cgit v1.1