Date: Wed, 19 Jun 2002 17:40:09 -0400 From: Daniel Eischen <eischen@vigrid.com> To: Andrew MacIntyre <andymac@bullseye.apana.org.au> Cc: freebsd-hackers@freebsd.org Subject: Re: signals in apps built with -pthread Message-ID: <3D10FA39.878E8703@vigrid.com> References: <Pine.OS2.4.32.0206192244550.74-200000@tenring.andymac.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Andrew MacIntyre wrote: > > [originally posted to -questions on June 2, with no response. If this > doesn't belong on this list, please say so.] > > This question is in the context of a scripting language interpreter > (Python) which is built with threads (gcc -pthread), but which is > used to run scripts which don't activate any threads. > > In such instances, signal handling differs from an interpreter built > without threads. > > The attached C code is a simple example of a signal handling situation > which works in the non-threaded interpreter, but fails in a threaded > interpreter. > > When compiled without -pthread (ie gcc -o sigp sigp.c), the attached code > behaves as expected like so: > > $ ./sigp > 1, > run 2 > $ > > When compiled with -pthread (ie gcc -pthread -o sigp sigp.c): > > $ ./sigp > > and then it hangs. Sending it a SIGHUP from another terminal has no > effect, but other likely signals (eg SIGINT) kill it. > > There appears to have been a thread on a closely related topic, found at > (long URL): > http://groups.google.com/groups?hl=en&lr=&threadm=fa.n97llov.1lict2d%40ifi.uio.no > > However, no information from that thread has illuminated the situation at > hand. Having two interpreter executables (with and without threads) is > unpalatable. > > Is there any way that the thread enabled interpreter can be setup to > handle signals in the same way, in the absence of activated threads, as it > would without thread support? (without disturbing the signal handling when > threads _are_ activated, of course...) > > Thanks for any advice, Try the patch included at the bottom. -- Dan Eischen Index: uthread/uthread_sigpending.c =================================================================== RCS file: /opt/FreeBSD/cvs/src/lib/libc_r/uthread/uthread_sigpending.c,v retrieving revision 1.6 diff -u -r1.6 uthread_sigpending.c --- uthread/uthread_sigpending.c 29 Jan 2000 22:53:53 -0000 1.6 +++ uthread/uthread_sigpending.c 19 Jun 2002 21:43:34 -0000 @@ -31,6 +31,9 @@ * * $FreeBSD: src/lib/libc_r/uthread/uthread_sigpending.c,v 1.6 2000/01/29 22:53:53 jasone Exp $ */ +#include <sys/param.h> +#include <sys/types.h> +#include <sys/signalvar.h> #include <signal.h> #include <errno.h> #ifdef _THREAD_SAFE @@ -40,6 +43,7 @@ int _sigpending(sigset_t * set) { + sigset_t sigset; int ret = 0; /* Check for a null signal set pointer: */ @@ -49,7 +53,10 @@ } else { *set = _thread_run->sigpend; + sigset = _process_sigpending; + SIGSETOR(*set, sigset); } + /* Return the completion status: */ return (ret); } Index: uthread/uthread_sigsuspend.c =================================================================== RCS file: /opt/FreeBSD/cvs/src/lib/libc_r/uthread/uthread_sigsuspend.c,v retrieving revision 1.9 diff -u -r1.9 uthread_sigsuspend.c --- uthread/uthread_sigsuspend.c 27 Jan 2000 23:07:19 -0000 1.9 +++ uthread/uthread_sigsuspend.c 19 Jun 2002 21:35:57 -0000 @@ -31,6 +31,9 @@ * * $FreeBSD: src/lib/libc_r/uthread/uthread_sigsuspend.c,v 1.9 2000/01/27 23:07:19 jasone Exp $ */ +#include <sys/param.h> +#include <sys/types.h> +#include <sys/signalvar.h> #include <signal.h> #include <errno.h> #ifdef _THREAD_SAFE @@ -41,7 +44,7 @@ _sigsuspend(const sigset_t * set) { int ret = -1; - sigset_t oset; + sigset_t oset, sigset; /* Check if a new signal set was provided by the caller: */ if (set != NULL) { @@ -51,14 +54,30 @@ /* Change the caller's mask: */ _thread_run->sigmask = *set; - /* Wait for a signal: */ - _thread_kern_sched_state(PS_SIGSUSPEND, __FILE__, __LINE__); - - /* Always return an interrupted error: */ - errno = EINTR; + /* + * Check if there are pending signals for the running + * thread or process that aren't blocked: + */ + sigset = _thread_run->sigpend; + SIGSETOR(sigset, _process_sigpending); + SIGSETNAND(sigset, _thread_run->sigmask); + if (SIGNOTEMPTY(sigset)) { + /* + * Call the kernel scheduler which will safely + * install a signal frame for the running thread: + */ + _thread_kern_sched_sig(); + } else { + /* Wait for a signal: */ + _thread_kern_sched_state(PS_SIGSUSPEND, + __FILE__, __LINE__); + } /* Restore the signal mask: */ _thread_run->sigmask = oset; + + /* Always return an interrupted error: */ + errno = EINTR; } else { /* Return an invalid argument error: */ errno = EINVAL; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3D10FA39.878E8703>