1bb535300SJeff Roberson /* 2bb535300SJeff Roberson * Copyright (c) 2003 Jeffrey Roberson <jeff@freebsd.org> 3bb535300SJeff Roberson * Copyright (c) 2003 Jonathan Mini <mini@freebsd.org> 4bb535300SJeff Roberson * All rights reserved. 5bb535300SJeff Roberson * 6bb535300SJeff Roberson * Redistribution and use in source and binary forms, with or without 7bb535300SJeff Roberson * modification, are permitted provided that the following conditions 8bb535300SJeff Roberson * are met: 9bb535300SJeff Roberson * 1. Redistributions of source code must retain the above copyright 10bb535300SJeff Roberson * notice unmodified, this list of conditions, and the following 11bb535300SJeff Roberson * disclaimer. 12bb535300SJeff Roberson * 2. Redistributions in binary form must reproduce the above copyright 13bb535300SJeff Roberson * notice, this list of conditions and the following disclaimer in the 14bb535300SJeff Roberson * documentation and/or other materials provided with the distribution. 15bb535300SJeff Roberson * 16bb535300SJeff Roberson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17bb535300SJeff Roberson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18bb535300SJeff Roberson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19bb535300SJeff Roberson * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20bb535300SJeff Roberson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21bb535300SJeff Roberson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22bb535300SJeff Roberson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23bb535300SJeff Roberson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24bb535300SJeff Roberson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25bb535300SJeff Roberson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26bb535300SJeff Roberson * 27bb535300SJeff Roberson * $FreeBSD$ 28bb535300SJeff Roberson */ 29bb535300SJeff Roberson 30bb535300SJeff Roberson #include <sys/param.h> 31bb535300SJeff Roberson #include <sys/types.h> 32bb535300SJeff Roberson #include <sys/signalvar.h> 33bb535300SJeff Roberson #include <signal.h> 34bb535300SJeff Roberson #include <fcntl.h> 35bb535300SJeff Roberson #include <unistd.h> 36bb535300SJeff Roberson #include <setjmp.h> 37bb535300SJeff Roberson #include <errno.h> 38bb535300SJeff Roberson #include <pthread.h> 39bb535300SJeff Roberson #include "thr_private.h" 40bb535300SJeff Roberson 41bb535300SJeff Roberson /* #define DEBUG_SIGNAL */ 42bb535300SJeff Roberson #ifdef DEBUG_SIGNAL 43bb535300SJeff Roberson #define DBG_MSG stdout_debug 44bb535300SJeff Roberson #else 45bb535300SJeff Roberson #define DBG_MSG(x...) 46bb535300SJeff Roberson #endif 47bb535300SJeff Roberson 48bb535300SJeff Roberson __weak_reference(_sigprocmask, sigprocmask); 49bb535300SJeff Roberson 50bb535300SJeff Roberson int 51bb535300SJeff Roberson _sigprocmask(int how, const sigset_t *set, sigset_t *oset) 52bb535300SJeff Roberson { 53bb535300SJeff Roberson sigset_t new; 54bb535300SJeff Roberson 55bb535300SJeff Roberson /* 56bb535300SJeff Roberson * Make sure applications can't unblock our synchronization 57bb535300SJeff Roberson * signal. We always want to take this with sigwait(). 58bb535300SJeff Roberson */ 59bb535300SJeff Roberson if (set != NULL) { 60bb535300SJeff Roberson new = *set; 61bb535300SJeff Roberson switch (how) { 62bb535300SJeff Roberson case SIG_BLOCK: 63bb535300SJeff Roberson case SIG_SETMASK: 64bb535300SJeff Roberson SIGADDSET(new, SIGTHR); 65bb535300SJeff Roberson break; 66bb535300SJeff Roberson case SIG_UNBLOCK: 67bb535300SJeff Roberson SIGDELSET(new, SIGTHR); 68bb535300SJeff Roberson break; 69bb535300SJeff Roberson default: 70bb535300SJeff Roberson break; 71bb535300SJeff Roberson } 72bb535300SJeff Roberson set = &new; 73bb535300SJeff Roberson } 74bb535300SJeff Roberson 75bb535300SJeff Roberson return (__sys_sigprocmask(how, set, oset)); 76bb535300SJeff Roberson } 77bb535300SJeff Roberson 78bb535300SJeff Roberson __weak_reference(_pthread_sigmask, pthread_sigmask); 79bb535300SJeff Roberson 80bb535300SJeff Roberson int 81bb535300SJeff Roberson _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) 82bb535300SJeff Roberson { 83bb535300SJeff Roberson int error; 84bb535300SJeff Roberson 85bb535300SJeff Roberson /* 86bb535300SJeff Roberson * This always sets the mask on the current thread. 87bb535300SJeff Roberson */ 88bb535300SJeff Roberson error = sigprocmask(how, set, oset); 89bb535300SJeff Roberson 90bb535300SJeff Roberson /* 91bb535300SJeff Roberson * pthread_sigmask returns errno or success while sigprocmask returns 92bb535300SJeff Roberson * -1 and sets errno. 93bb535300SJeff Roberson */ 94bb535300SJeff Roberson if (error == -1) 95bb535300SJeff Roberson error = errno; 96bb535300SJeff Roberson 97bb535300SJeff Roberson return (error); 98bb535300SJeff Roberson } 99bb535300SJeff Roberson 100bb535300SJeff Roberson 101bb535300SJeff Roberson __weak_reference(_pthread_kill, pthread_kill); 102bb535300SJeff Roberson 103bb535300SJeff Roberson int 104bb535300SJeff Roberson _pthread_kill(pthread_t pthread, int sig) 105bb535300SJeff Roberson { 106bb535300SJeff Roberson 107bb535300SJeff Roberson if (_thread_initial == NULL) 108bb535300SJeff Roberson _thread_init(); 109bb535300SJeff Roberson return (thr_kill(pthread->thr_id, sig)); 110bb535300SJeff Roberson } 111bb535300SJeff Roberson 112bb535300SJeff Roberson /* 113bb535300SJeff Roberson * User thread signal handler wrapper. 114bb535300SJeff Roberson */ 115bb535300SJeff Roberson void 116bb535300SJeff Roberson _thread_sig_wrapper(int sig, siginfo_t *info, ucontext_t *context) 117bb535300SJeff Roberson { 118bb535300SJeff Roberson struct pthread_state_data psd; 119bb535300SJeff Roberson struct pthread *curthread = _get_curthread(); 120bb535300SJeff Roberson __siginfohandler_t *handler; 121bb535300SJeff Roberson 122bb535300SJeff Roberson GIANT_LOCK(curthread); 123bb535300SJeff Roberson /* Save the thread's previous state. */ 124bb535300SJeff Roberson curthread->data = psd.psd_wait_data; 125bb535300SJeff Roberson curthread->state = psd.psd_state; 126bb535300SJeff Roberson curthread->flags = psd.psd_flags; 127bb535300SJeff Roberson 128bb535300SJeff Roberson /* Check the threads previous state: */ 129bb535300SJeff Roberson if (psd.psd_state != PS_RUNNING) { 130bb535300SJeff Roberson /* 131bb535300SJeff Roberson * Do a little cleanup handling for those threads in 132bb535300SJeff Roberson * queues before calling the signal handler. Signals 133bb535300SJeff Roberson * for these threads are temporarily blocked until 134bb535300SJeff Roberson * after cleanup handling. 135bb535300SJeff Roberson */ 136bb535300SJeff Roberson switch (psd.psd_state) { 137bb535300SJeff Roberson case PS_COND_WAIT: 138bb535300SJeff Roberson _cond_wait_backout(curthread); 139bb535300SJeff Roberson psd.psd_state = PS_RUNNING; 140bb535300SJeff Roberson break; 141bb535300SJeff Roberson 142bb535300SJeff Roberson case PS_MUTEX_WAIT: 143bb535300SJeff Roberson /* _mutex_lock_backout(curthread); XXXTHR */ 144bb535300SJeff Roberson psd.psd_state = PS_RUNNING; 145bb535300SJeff Roberson break; 146bb535300SJeff Roberson 147bb535300SJeff Roberson default: 148bb535300SJeff Roberson break; 149bb535300SJeff Roberson } 150bb535300SJeff Roberson } 151bb535300SJeff Roberson 152bb535300SJeff Roberson if (_thread_sigact[sig -1].sa_handler != NULL) { 153bb535300SJeff Roberson GIANT_UNLOCK(curthread); 154bb535300SJeff Roberson handler = (__siginfohandler_t *) 155bb535300SJeff Roberson _thread_sigact[sig - 1].sa_handler; 156bb535300SJeff Roberson handler(sig, info, context); 157bb535300SJeff Roberson GIANT_LOCK(curthread); 158bb535300SJeff Roberson } 159bb535300SJeff Roberson 160bb535300SJeff Roberson /* Restore the signal frame. */ 161bb535300SJeff Roberson psd.psd_wait_data = curthread->data; 162bb535300SJeff Roberson psd.psd_state = curthread->state; 163bb535300SJeff Roberson psd.psd_flags = curthread->flags & 164bb535300SJeff Roberson (PTHREAD_FLAGS_PRIVATE | PTHREAD_FLAGS_TRACE); 165bb535300SJeff Roberson GIANT_UNLOCK(curthread); 166bb535300SJeff Roberson } 167