Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libpthread More rototilling:
details: https://anonhg.NetBSD.org/src/rev/d8812ce0c407
branches: trunk
changeset: 542466:d8812ce0c407
user: nathanw <nathanw%NetBSD.org@localhost>
date: Thu Jan 30 01:12:42 2003 +0000
description:
More rototilling:
* Implement pthread_kill().
* Return the old thread mask, not the old process mask, in our
interpositioned sigaction call.
* Refer to _NSIG, not NSIG.
* Gut pthread_sigmask(). It was handling a lot of corner cases that
weren't legal anyway. Handle unblocked signals with a new
pthread__kill_self() routine (also used by pthread_kill()).
* Be more consistent with locking around pt_sigacts[].
diffstat:
lib/libpthread/pthread_sig.c | 298 ++++++++++++++++++++++++------------------
1 files changed, 167 insertions(+), 131 deletions(-)
diffs (truncated from 414 to 300 lines):
diff -r a5f16c3c288a -r d8812ce0c407 lib/libpthread/pthread_sig.c
--- a/lib/libpthread/pthread_sig.c Thu Jan 30 01:04:50 2003 +0000
+++ b/lib/libpthread/pthread_sig.c Thu Jan 30 01:12:42 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_sig.c,v 1.6 2003/01/28 21:04:37 jdolecek Exp $ */
+/* $NetBSD: pthread_sig.c,v 1.7 2003/01/30 01:12:42 nathanw Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -89,6 +89,9 @@
static pthread_cond_t pt_sigsuspended_cond = PTHREAD_COND_INITIALIZER;
+static void pthread__kill(pthread_t, pthread_t, int, int);
+static void pthread__kill_self(pthread_t, int, int);
+
static void
pthread__signal_tramp(int, int, void (*)(int, int, struct sigcontext *),
ucontext_t *, sigset_t *);
@@ -103,17 +106,44 @@
}
int
-/*ARGSUSED*/
pthread_kill(pthread_t thread, int sig)
{
+ pthread_t self;
+ void (*handler)(int);
- /* We only let the thread handle this signal if the action for
+ self = pthread__self();
+
+ SDPRINTF(("(pthread_kill %p) kill %p sig %d\n", self, thread, sig));
+
+ if ((sig < 0) || (sig >= _NSIG))
+ return EINVAL;
+ if (pthread__find(self, thread) != 0)
+ return ESRCH;
+
+ /*
+ * We only let the thread handle this signal if the action for
* the signal is an explicit handler. Otherwise we feed it to
* the kernel so that it can affect the whole process.
*/
+ pthread_spinlock(self, &pt_sigacts_lock);
+ handler = pt_sigacts[sig].sa_handler;
+ pthread_spinunlock(self, &pt_sigacts_lock);
- /* XXX implement me */
- return -1;
+ if (handler == SIG_IGN) {
+ SDPRINTF(("(pthread_kill %p) do nothing\n", self, thread, sig));
+ /* Do nothing */
+ } else if ((sig == SIGKILL) || (sig == SIGSTOP) ||
+ (handler == SIG_DFL)) {
+ /* Let the kernel do the work */
+ SDPRINTF(("(pthread_kill %p) kernel kill\n", self, thread, sig));
+ kill(getpid(), sig);
+ } else {
+ pthread_spinlock(self, &thread->pt_siglock);
+ pthread__kill(self, thread, sig, 0);
+ pthread_spinunlock(self, &thread->pt_siglock);
+ }
+
+ return 0;
}
@@ -125,16 +155,19 @@
int
__sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
+ struct sigaction realact;
+ sigset_t oldmask;
pthread_t self;
- struct sigaction realact;
-
+ int retval;
+
+ if ((sig <= 0) || (sig >= _NSIG))
+ return EINVAL;
+
self = pthread__self();
if (act != NULL) {
- if (sig <= 0 || sig >= _NSIG)
- return (EINVAL);
-
/* Save the information for our internal dispatch. */
pthread_spinlock(self, &pt_sigacts_lock);
+ oldmask = pt_sigacts[sig].sa_mask;
pt_sigacts[sig] = *act;
pthread_spinunlock(self, &pt_sigacts_lock);
/*
@@ -150,7 +183,11 @@
act = &realact;
}
- return (__libc_sigaction14(sig, act, oact));
+ retval = __libc_sigaction14(sig, act, oact);
+ if (oact && (retval == 0))
+ oact->sa_mask = oldmask;
+
+ return retval;
}
int
@@ -204,17 +241,17 @@
sig = ffs((int)ss->__bits[0]);
if (sig != 0)
return (sig);
-#if NSIG > 33
+#if _NSIG > 33
sig = ffs((int)ss->__bits[1]);
if (sig != 0)
return (sig + 32);
#endif
-#if NSIG > 65
+#if _NSIG > 65
sig = ffs((int)ss->__bits[2]);
if (sig != 0)
return (sig + 64);
#endif
-#if NSIG > 97
+#if _NSIG > 97
sig = ffs((int)ss->__bits[3]);
if (sig != 0)
return (sig + 96);
@@ -225,127 +262,75 @@
int
pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
{
+ sigset_t tmp, takelist;
pthread_t self;
- sigset_t tmp;
- int i, retval, unblocked, procmaskset;
- void (*handler)(int, int, struct sigcontext *);
- struct sigaction *act;
- struct sigcontext xxxsc;
- sigset_t oldmask, takelist;
+ int i;
self = pthread__self();
-
- retval = 0;
- unblocked = 0;
- if (set != NULL) {
- pthread_spinlock(self, &self->pt_siglock);
- if (how == SIG_BLOCK) {
- __sigplusset(set, &self->pt_sigmask);
- /*
- * Blocking of signals that are now
- * blocked by all threads will be done
- * lazily, at signal delivery time.
- */
- } else if (how == SIG_UNBLOCK) {
- pthread_spinlock(self, &pt_process_siglock);
- __sigminusset(set, &self->pt_sigmask);
- /*
- * Unblock any signals that were blocked
- * process-wide before this.
- */
- tmp = pt_process_sigmask;
- __sigminusset(set, &tmp);
- if (!__sigsetequal(&tmp, &pt_process_sigmask))
- pt_process_sigmask = tmp;
- unblocked = 1;
- } else if (how == SIG_SETMASK) {
- pthread_spinlock(self, &pt_process_siglock);
- self->pt_sigmask = *set;
- SDPRINTF(("(pt_sigmask %p) (set) set thread mask to "
- "%08x\n", self, self->pt_sigmask.__bits[0]));
- /*
- * Unblock any signals that were blocked
- * process-wide before this.
- */
- tmp = pt_process_sigmask;
- __sigandset(set, &tmp);
- if (!__sigsetequal(&tmp, &pt_process_sigmask))
- pt_process_sigmask = tmp;
- unblocked = 1; /* Well, maybe */
- } else
- retval = EINVAL;
- }
-
- if (unblocked) {
- SDPRINTF(("(pt_sigmask %p) Process mask was changed to %08x\n",
- self, pt_process_sigmask.__bits[0]));
- /* See if there are any signals to take */
- __sigemptyset14(&takelist);
- while ((i = firstsig(&self->pt_siglist)) != 0) {
- if (!__sigismember14(&self->pt_sigmask, i)) {
- __sigaddset14(&takelist, i);
- __sigdelset14(&self->pt_siglist, i);
- }
- }
- while ((i = firstsig(&pt_process_siglist)) != 0) {
- if (!__sigismember14(&self->pt_sigmask, i)) {
- __sigaddset14(&takelist, i);
- __sigdelset14(&pt_process_siglist, i);
- }
- }
-
- procmaskset = 0;
- while ((i = firstsig(&takelist)) != 0) {
- if (!__sigismember14(&self->pt_sigmask, i)) {
- /* Take the signal */
- act = &pt_sigacts[i];
- oldmask = self->pt_sigmask;
- __sigplusset(&self->pt_sigmask,
- &act->sa_mask);
- __sigaddset14(&self->pt_sigmask, i);
- pthread_spinunlock(self, &pt_process_siglock);
- pthread_spinunlock(self, &self->pt_siglock);
- SDPRINTF(("(pt_sigmask %p) taking unblocked signal %d\n", self, i));
- handler =
- (void (*)(int, int, struct sigcontext *))
- act->sa_handler;
- handler(i, 0, &xxxsc);
- pthread_spinlock(self, &self->pt_siglock);
- pthread_spinlock(self, &pt_process_siglock);
- __sigdelset14(&takelist, i);
- /* Reset masks */
- self->pt_sigmask = oldmask;
- tmp = pt_process_sigmask;
- __sigandset(&oldmask, &tmp);
- if (!__sigsetequal(&tmp, &pt_process_sigmask)){
- pt_process_sigmask = tmp;
- SDPRINTF(("(pt_sigmask %p) setting proc sigmask to %08x\n", pt_process_sigmask.__bits[0]));
- __sigprocmask14(SIG_SETMASK,
- &pt_process_sigmask, NULL);
- procmaskset = 1;
- }
- }
- }
- if (!procmaskset) {
- SDPRINTF(("(pt_sigmask %p) setting proc sigmask to %08x\n", self, pt_process_sigmask.__bits[0]));
- __sigprocmask14(SIG_SETMASK, &pt_process_sigmask, NULL);
- }
- }
- if (set != NULL) {
- if ((how == SIG_UNBLOCK) || (how == SIG_SETMASK))
- pthread_spinunlock(self, &pt_process_siglock);
- pthread_spinunlock(self, &self->pt_siglock);
- }
-
/*
* While other threads may read a process's sigmask,
* they won't write it, so we don't need to lock our reads of it.
*/
- if (oset != NULL) {
+ if (oset != NULL)
*oset = self->pt_sigmask;
+
+ if (set == NULL)
+ return 0;
+
+ pthread_spinlock(self, &self->pt_siglock);
+ if (how == SIG_BLOCK) {
+ __sigplusset(set, &self->pt_sigmask);
+ /*
+ * Blocking of signals that are now
+ * blocked by all threads will be done
+ * lazily, at signal delivery time.
+ */
+ pthread_spinunlock(self, &self->pt_siglock);
+ return 0;
+ } else if (how == SIG_UNBLOCK)
+ __sigminusset(set, &self->pt_sigmask);
+ else if (how == SIG_SETMASK)
+ self->pt_sigmask = *set;
+ else {
+ pthread_spinunlock(self, &self->pt_siglock);
+ return EINVAL;
}
- return retval;
+ /* See if there are any signals to take */
+ __sigemptyset14(&takelist);
+ while ((i = firstsig(&self->pt_siglist)) != 0) {
+ if (!__sigismember14(&self->pt_sigmask, i)) {
+ __sigaddset14(&takelist, i);
+ __sigdelset14(&self->pt_siglist, i);
+ }
+ }
+ pthread_spinlock(self, &pt_process_siglock);
+ while ((i = firstsig(&pt_process_siglist)) != 0) {
+ if (!__sigismember14(&self->pt_sigmask, i)) {
+ __sigaddset14(&takelist, i);
+ __sigdelset14(&pt_process_siglist, i);
+ }
+ }
+ /* Unblock any signals that were blocked process-wide before this. */
+ tmp = pt_process_sigmask;
+ __sigandset(&self->pt_sigmask, &tmp);
+ if (!__sigsetequal(&tmp, &pt_process_sigmask)) {
+ pt_process_sigmask = tmp;
+ __sigprocmask14(SIG_SETMASK, &pt_process_sigmask, NULL);
+ }
+ pthread_spinunlock(self, &pt_process_siglock);
+
Home |
Main Index |
Thread Index |
Old Index