aboutsummaryrefslogtreecommitdiff
path: root/lib/libpthread/thread/thr_sigmask.c
diff options
context:
space:
mode:
authorDaniel Eischen <deischen@FreeBSD.org>2003-04-18 05:04:16 +0000
committerDaniel Eischen <deischen@FreeBSD.org>2003-04-18 05:04:16 +0000
commita0240e2cb0b1ef8e5b61930ac2b850c884daaba8 (patch)
tree46bc1e113ddc7c1ed88e4fa724039df8664c963a /lib/libpthread/thread/thr_sigmask.c
parentb025fc9a31c85b9cde9969e1fea55ea4caf650d5 (diff)
downloadsrc-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/libpthread/thread/thr_sigmask.c')
-rw-r--r--lib/libpthread/thread/thr_sigmask.c76
1 files changed, 52 insertions, 24 deletions
diff --git a/lib/libpthread/thread/thr_sigmask.c b/lib/libpthread/thread/thr_sigmask.c
index f98c4218424a..d9cb8396485f 100644
--- a/lib/libpthread/thread/thr_sigmask.c
+++ b/lib/libpthread/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);
}