diff options
author | Daniel Eischen <deischen@FreeBSD.org> | 2003-04-18 05:04:16 +0000 |
---|---|---|
committer | Daniel Eischen <deischen@FreeBSD.org> | 2003-04-18 05:04:16 +0000 |
commit | a0240e2cb0b1ef8e5b61930ac2b850c884daaba8 (patch) | |
tree | 46bc1e113ddc7c1ed88e4fa724039df8664c963a /lib/libkse/thread/thr_sigmask.c | |
parent | b025fc9a31c85b9cde9969e1fea55ea4caf650d5 (diff) | |
download | src-a0240e2cb0b1ef8e5b61930ac2b850c884daaba8.tar.gz src-a0240e2cb0b1ef8e5b61930ac2b850c884daaba8.zip |
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
Notes
Notes:
svn path=/head/; revision=113658
Diffstat (limited to 'lib/libkse/thread/thr_sigmask.c')
-rw-r--r-- | lib/libkse/thread/thr_sigmask.c | 76 |
1 files changed, 52 insertions, 24 deletions
diff --git a/lib/libkse/thread/thr_sigmask.c b/lib/libkse/thread/thr_sigmask.c index f98c4218424a..d9cb8396485f 100644 --- a/lib/libkse/thread/thr_sigmask.c +++ b/lib/libkse/thread/thr_sigmask.c @@ -36,6 +36,7 @@ #include <sys/signalvar.h> #include <errno.h> #include <signal.h> +#include <string.h> #include <pthread.h> #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); } |