1/* 2 * signal.c 3 * 4 * Description: 5 * Thread-aware signal functions. 6 * 7 * -------------------------------------------------------------------------- 8 * 9 * Pthreads-win32 - POSIX Threads Library for Win32 10 * Copyright(C) 1998 John E. Bossom 11 * Copyright(C) 1999,2005 Pthreads-win32 contributors 12 * 13 * Contact Email: rpj@callisto.canberra.edu.au 14 * 15 * The current list of contributors is contained 16 * in the file CONTRIBUTORS included with the source 17 * code distribution. The list can also be seen at the 18 * following World Wide Web location: 19 * http://sources.redhat.com/pthreads-win32/contributors.html 20 * 21 * This library is free software; you can redistribute it and/or 22 * modify it under the terms of the GNU Lesser General Public 23 * License as published by the Free Software Foundation; either 24 * version 2 of the License, or (at your option) any later version. 25 * 26 * This library is distributed in the hope that it will be useful, 27 * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 29 * Lesser General Public License for more details. 30 * 31 * You should have received a copy of the GNU Lesser General Public 32 * License along with this library in the file COPYING.LIB; 33 * if not, write to the Free Software Foundation, Inc., 34 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 35 */ 36 37/* 38 * Possible future strategy for implementing pthread_kill() 39 * ======================================================== 40 * 41 * Win32 does not implement signals. 42 * Signals are simply software interrupts. 43 * pthread_kill() asks the system to deliver a specified 44 * signal (interrupt) to a specified thread in the same 45 * process. 46 * Signals are always asynchronous (no deferred signals). 47 * Pthread-win32 has an async cancelation mechanism. 48 * A similar system can be written to deliver signals 49 * within the same process (on ix86 processors at least). 50 * 51 * Each thread maintains information about which 52 * signals it will respond to. Handler routines 53 * are set on a per-process basis - not per-thread. 54 * When signalled, a thread will check it's sigmask 55 * and, if the signal is not being ignored, call the 56 * handler routine associated with the signal. The 57 * thread must then (except for some signals) return to 58 * the point where it was interrupted. 59 * 60 * Ideally the system itself would check the target thread's 61 * mask before possibly needlessly bothering the thread 62 * itself. This could be done by pthread_kill(), that is, 63 * in the signaling thread since it has access to 64 * all pthread_t structures. It could also retrieve 65 * the handler routine address to minimise the target 66 * threads response overhead. This may also simplify 67 * serialisation of the access to the per-thread signal 68 * structures. 69 * 70 * pthread_kill() eventually calls a routine similar to 71 * ptw32_cancel_thread() which manipulates the target 72 * threads processor context to cause the thread to 73 * run the handler launcher routine. pthread_kill() must 74 * save the target threads current context so that the 75 * handler launcher routine can restore the context after 76 * the signal handler has returned. Some handlers will not 77 * return, eg. the default SIGKILL handler may simply 78 * call pthread_exit(). 79 * 80 * The current context is saved in the target threads 81 * pthread_t structure. 82 */ 83 84#include "pthread.h" 85#include "implement.h" 86 87#if defined(HAVE_SIGSET_T) 88 89static void 90ptw32_signal_thread () 91{ 92} 93 94static void 95ptw32_signal_callhandler () 96{ 97} 98 99int 100pthread_sigmask (int how, sigset_t const *set, sigset_t * oset) 101{ 102 pthread_t thread = pthread_self (); 103 104 if (thread.p == NULL) 105 { 106 return ENOENT; 107 } 108 109 /* Validate the `how' argument. */ 110 if (set != NULL) 111 { 112 switch (how) 113 { 114 case SIG_BLOCK: 115 break; 116 case SIG_UNBLOCK: 117 break; 118 case SIG_SETMASK: 119 break; 120 default: 121 /* Invalid `how' argument. */ 122 return EINVAL; 123 } 124 } 125 126 /* Copy the old mask before modifying it. */ 127 if (oset != NULL) 128 { 129 memcpy (oset, &(thread.p->sigmask), sizeof (sigset_t)); 130 } 131 132 if (set != NULL) 133 { 134 unsigned int i; 135 136 /* FIXME: this code assumes that sigmask is an even multiple of 137 the size of a long integer. */ 138 139 unsigned long *src = (unsigned long const *) set; 140 unsigned long *dest = (unsigned long *) &(thread.p->sigmask); 141 142 switch (how) 143 { 144 case SIG_BLOCK: 145 for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++) 146 { 147 /* OR the bit field longword-wise. */ 148 *dest++ |= *src++; 149 } 150 break; 151 case SIG_UNBLOCK: 152 for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++) 153 { 154 /* XOR the bitfield longword-wise. */ 155 *dest++ ^= *src++; 156 } 157 case SIG_SETMASK: 158 /* Replace the whole sigmask. */ 159 memcpy (&(thread.p->sigmask), set, sizeof (sigset_t)); 160 break; 161 } 162 } 163 164 return 0; 165} 166 167int 168sigwait (const sigset_t * set, int *sig) 169{ 170 /* This routine is a cancellation point */ 171 pthread_test_cancel(); 172} 173 174int 175sigaction (int signum, const struct sigaction *act, struct sigaction *oldact) 176{ 177} 178 179#endif /* HAVE_SIGSET_T */ 180