thr_sig.c (117366) | thr_sig.c (117706) |
---|---|
1/* 2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * | 1/* 2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * |
32 * $FreeBSD: head/lib/libkse/thread/thr_sig.c 117366 2003-07-09 22:30:55Z davidxu $ | 32 * $FreeBSD: head/lib/libkse/thread/thr_sig.c 117706 2003-07-17 23:02:30Z davidxu $ |
33 */ 34#include <sys/param.h> 35#include <sys/types.h> 36#include <sys/signalvar.h> 37#include <signal.h> 38#include <errno.h> 39#include <fcntl.h> 40#include <unistd.h> 41#include <string.h> 42#include <pthread.h> 43#include "thr_private.h" 44#include "pthread_md.h" 45 46/* Prototypes: */ 47static void build_siginfo(siginfo_t *info, int signo); | 33 */ 34#include <sys/param.h> 35#include <sys/types.h> 36#include <sys/signalvar.h> 37#include <signal.h> 38#include <errno.h> 39#include <fcntl.h> 40#include <unistd.h> 41#include <string.h> 42#include <pthread.h> 43#include "thr_private.h" 44#include "pthread_md.h" 45 46/* Prototypes: */ 47static void build_siginfo(siginfo_t *info, int signo); |
48static void thr_sig_check_state(struct pthread *pthread, int sig); | 48#ifndef SYSTEM_SCOPE_ONLY |
49static struct pthread *thr_sig_find(struct kse *curkse, int sig, 50 siginfo_t *info); 51static void handle_special_signals(struct kse *curkse, int sig); | 49static struct pthread *thr_sig_find(struct kse *curkse, int sig, 50 siginfo_t *info); 51static void handle_special_signals(struct kse *curkse, int sig); |
52#endif |
|
52static void thr_sigframe_add(struct pthread *thread); 53static void thr_sigframe_restore(struct pthread *thread, 54 struct pthread_sigframe *psf); 55static void thr_sigframe_save(struct pthread *thread, 56 struct pthread_sigframe *psf); 57 | 53static void thr_sigframe_add(struct pthread *thread); 54static void thr_sigframe_restore(struct pthread *thread, 55 struct pthread_sigframe *psf); 56static void thr_sigframe_save(struct pthread *thread, 57 struct pthread_sigframe *psf); 58 |
59#define SA_KILL 0x01 /* terminates process by default */ 60#define SA_STOP 0x02 61#define SA_CONT 0x04 62 63static int sigproptbl[NSIG] = { 64 SA_KILL, /* SIGHUP */ 65 SA_KILL, /* SIGINT */ 66 SA_KILL, /* SIGQUIT */ 67 SA_KILL, /* SIGILL */ 68 SA_KILL, /* SIGTRAP */ 69 SA_KILL, /* SIGABRT */ 70 SA_KILL, /* SIGEMT */ 71 SA_KILL, /* SIGFPE */ 72 SA_KILL, /* SIGKILL */ 73 SA_KILL, /* SIGBUS */ 74 SA_KILL, /* SIGSEGV */ 75 SA_KILL, /* SIGSYS */ 76 SA_KILL, /* SIGPIPE */ 77 SA_KILL, /* SIGALRM */ 78 SA_KILL, /* SIGTERM */ 79 0, /* SIGURG */ 80 SA_STOP, /* SIGSTOP */ 81 SA_STOP, /* SIGTSTP */ 82 SA_CONT, /* SIGCONT */ 83 0, /* SIGCHLD */ 84 SA_STOP, /* SIGTTIN */ 85 SA_STOP, /* SIGTTOU */ 86 0, /* SIGIO */ 87 SA_KILL, /* SIGXCPU */ 88 SA_KILL, /* SIGXFSZ */ 89 SA_KILL, /* SIGVTALRM */ 90 SA_KILL, /* SIGPROF */ 91 0, /* SIGWINCH */ 92 0, /* SIGINFO */ 93 SA_KILL, /* SIGUSR1 */ 94 SA_KILL /* SIGUSR2 */ 95}; 96 |
|
58/* #define DEBUG_SIGNAL */ 59#ifdef DEBUG_SIGNAL 60#define DBG_MSG stdout_debug 61#else 62#define DBG_MSG(x...) 63#endif 64 65/* --- 62 unchanged lines hidden (view full) --- 128 * 129 * 3) A thread in sigsuspend() where the signal is not in the 130 * thread's suspended signal mask. 131 * 132 * 4) Any thread (first found/easiest to deliver) that has the 133 * signal unmasked. 134 */ 135 | 97/* #define DEBUG_SIGNAL */ 98#ifdef DEBUG_SIGNAL 99#define DBG_MSG stdout_debug 100#else 101#define DBG_MSG(x...) 102#endif 103 104/* --- 62 unchanged lines hidden (view full) --- 167 * 168 * 3) A thread in sigsuspend() where the signal is not in the 169 * thread's suspended signal mask. 170 * 171 * 4) Any thread (first found/easiest to deliver) that has the 172 * signal unmasked. 173 */ 174 |
175#ifndef SYSTEM_SCOPE_ONLY 176 |
|
136static void * 137sig_daemon(void *arg /* Unused */) 138{ 139 int i; 140 kse_critical_t crit; 141 struct timespec ts; 142 sigset_t set; 143 struct kse *curkse; 144 struct pthread *curthread = _get_curthread(); 145 | 177static void * 178sig_daemon(void *arg /* Unused */) 179{ 180 int i; 181 kse_critical_t crit; 182 struct timespec ts; 183 sigset_t set; 184 struct kse *curkse; 185 struct pthread *curthread = _get_curthread(); 186 |
146 DBG_MSG("signal daemon started\n"); | 187 DBG_MSG("signal daemon started(%p)\n", curthread); |
147 148 curthread->name = strdup("signal thread"); 149 crit = _kse_critical_enter(); 150 curkse = _get_curkse(); | 188 189 curthread->name = strdup("signal thread"); 190 crit = _kse_critical_enter(); 191 curkse = _get_curkse(); |
192 193 /* 194 * Daemon thread is a bound thread and we must be created with 195 * all signals masked 196 */ 197#if 0 |
|
151 SIGFILLSET(set); 152 __sys_sigprocmask(SIG_SETMASK, &set, NULL); | 198 SIGFILLSET(set); 199 __sys_sigprocmask(SIG_SETMASK, &set, NULL); |
200#endif |
|
153 __sys_sigpending(&set); 154 ts.tv_sec = 0; 155 ts.tv_nsec = 0; 156 while (1) { 157 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 158 _thr_proc_sigpending = set; 159 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 160 for (i = 1; i <= _SIG_MAXSIG; i++) { --- 7 unchanged lines hidden (view full) --- 168 KMF_NOUPCALL | KMF_NOCOMPLETED | KMF_WAITSIGEVENT; 169 kse_release(&ts); 170 curkse->k_mbx.km_flags = 0; 171 set = curkse->k_mbx.km_sigscaught; 172 } 173 return (0); 174} 175 | 201 __sys_sigpending(&set); 202 ts.tv_sec = 0; 203 ts.tv_nsec = 0; 204 while (1) { 205 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 206 _thr_proc_sigpending = set; 207 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 208 for (i = 1; i <= _SIG_MAXSIG; i++) { --- 7 unchanged lines hidden (view full) --- 216 KMF_NOUPCALL | KMF_NOCOMPLETED | KMF_WAITSIGEVENT; 217 kse_release(&ts); 218 curkse->k_mbx.km_flags = 0; 219 set = curkse->k_mbx.km_sigscaught; 220 } 221 return (0); 222} 223 |
224 |
|
176/* Utility function to create signal daemon thread */ 177int 178_thr_start_sig_daemon(void) 179{ 180 pthread_attr_t attr; 181 sigset_t sigset, oldset; | 225/* Utility function to create signal daemon thread */ 226int 227_thr_start_sig_daemon(void) 228{ 229 pthread_attr_t attr; 230 sigset_t sigset, oldset; |
182 | 231 |
183 SIGFILLSET(sigset); 184 pthread_sigmask(SIG_SETMASK, &sigset, &oldset); 185 pthread_attr_init(&attr); 186 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); 187 /* sigmask will be inherited */ 188 if (pthread_create(&_thr_sig_daemon, &attr, sig_daemon, NULL)) 189 PANIC("can not create signal daemon thread!\n"); 190 pthread_attr_destroy(&attr); --- 10 unchanged lines hidden (view full) --- 201_thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info) 202{ 203 struct pthread *thread; 204 205 DBG_MSG(">>> _thr_sig_dispatch(%d)\n", sig); 206 207 /* Some signals need special handling: */ 208 handle_special_signals(curkse, sig); | 232 SIGFILLSET(sigset); 233 pthread_sigmask(SIG_SETMASK, &sigset, &oldset); 234 pthread_attr_init(&attr); 235 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); 236 /* sigmask will be inherited */ 237 if (pthread_create(&_thr_sig_daemon, &attr, sig_daemon, NULL)) 238 PANIC("can not create signal daemon thread!\n"); 239 pthread_attr_destroy(&attr); --- 10 unchanged lines hidden (view full) --- 250_thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info) 251{ 252 struct pthread *thread; 253 254 DBG_MSG(">>> _thr_sig_dispatch(%d)\n", sig); 255 256 /* Some signals need special handling: */ 257 handle_special_signals(curkse, sig); |
258 259 /* Check if the signal requires a dump of thread information: */ 260 if (sig == SIGINFO) { 261 /* Dump thread information to file: */ 262 _thread_dump_info(); 263 } 264 |
|
209 while ((thread = thr_sig_find(curkse, sig, info)) != NULL) { 210 /* 211 * Setup the target thread to receive the signal: 212 */ 213 DBG_MSG("Got signal %d, selecting thread %p\n", sig, thread); 214 KSE_SCHED_LOCK(curkse, thread->kseg); 215 if ((thread->state == PS_DEAD) || 216 (thread->state == PS_DEADLOCK) || --- 11 unchanged lines hidden (view full) --- 228 KSE_SCHED_UNLOCK(curkse, thread->kseg); 229 _thr_ref_delete(NULL, thread); 230 break; 231 } 232 } 233 DBG_MSG("<<< _thr_sig_dispatch\n"); 234} 235 | 265 while ((thread = thr_sig_find(curkse, sig, info)) != NULL) { 266 /* 267 * Setup the target thread to receive the signal: 268 */ 269 DBG_MSG("Got signal %d, selecting thread %p\n", sig, thread); 270 KSE_SCHED_LOCK(curkse, thread->kseg); 271 if ((thread->state == PS_DEAD) || 272 (thread->state == PS_DEADLOCK) || --- 11 unchanged lines hidden (view full) --- 284 KSE_SCHED_UNLOCK(curkse, thread->kseg); 285 _thr_ref_delete(NULL, thread); 286 break; 287 } 288 } 289 DBG_MSG("<<< _thr_sig_dispatch\n"); 290} 291 |
292#endif /* ! SYSTEM_SCOPE_ONLY */ 293 294static __inline int 295sigprop(int sig) 296{ 297 298 if (sig > 0 && sig < NSIG) 299 return (sigproptbl[_SIG_IDX(sig)]); 300 return (0); 301} 302 |
|
236void 237_thr_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp) 238{ 239 __siginfohandler_t *sigfunc; | 303void 304_thr_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp) 305{ 306 __siginfohandler_t *sigfunc; |
307 struct pthread *curthread; |
|
240 struct kse *curkse; | 308 struct kse *curkse; |
309 struct sigaction act; 310 int sa_flags, err_save, intr_save, timeout_save; |
|
241 | 311 |
312 DBG_MSG(">>> _thr_sig_handler(%d)\n", sig); 313 |
|
242 curkse = _get_curkse(); 243 if ((curkse == NULL) || ((curkse->k_flags & KF_STARTED) == 0)) { 244 /* Upcalls are not yet started; just call the handler. */ 245 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 246 if (((__sighandler_t *)sigfunc != SIG_DFL) && 247 ((__sighandler_t *)sigfunc != SIG_IGN) && 248 (sigfunc != (__siginfohandler_t *)_thr_sig_handler)) { 249 if (((_thread_sigact[sig - 1].sa_flags & SA_SIGINFO) 250 != 0) || (info == NULL)) 251 (*(sigfunc))(sig, info, ucp); 252 else 253 (*(sigfunc))(sig, 254 (siginfo_t*)(intptr_t)info->si_code, ucp); 255 } | 314 curkse = _get_curkse(); 315 if ((curkse == NULL) || ((curkse->k_flags & KF_STARTED) == 0)) { 316 /* Upcalls are not yet started; just call the handler. */ 317 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 318 if (((__sighandler_t *)sigfunc != SIG_DFL) && 319 ((__sighandler_t *)sigfunc != SIG_IGN) && 320 (sigfunc != (__siginfohandler_t *)_thr_sig_handler)) { 321 if (((_thread_sigact[sig - 1].sa_flags & SA_SIGINFO) 322 != 0) || (info == NULL)) 323 (*(sigfunc))(sig, info, ucp); 324 else 325 (*(sigfunc))(sig, 326 (siginfo_t*)(intptr_t)info->si_code, ucp); 327 } |
328 329 return; |
|
256 } | 330 } |
257 else { 258 /* Nothing. */ 259 DBG_MSG("Got signal %d\n", sig); 260 /* XXX Bound thread will fall into this... */ | 331 332 curthread = _get_curthread(); 333 if (curthread == NULL) 334 PANIC("No current thread.\n"); 335 if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) 336 PANIC("Thread is not system scope.\n"); 337 if (curthread->flags & THR_FLAGS_EXITING) 338 return; 339 curkse = _get_curkse(); 340 /* 341 * If thread is in critical region or if thread is on 342 * the way of state transition, then latch signal into buffer. 343 */ 344 if (_kse_in_critical() || THR_IN_CRITICAL(curthread) || 345 (curthread->state != PS_RUNNING && curthread->curframe == NULL)) { 346 DBG_MSG(">>> _thr_sig_handler(%d) in critical\n", sig); 347 curthread->siginfo[sig-1] = *info; 348 curthread->check_pending = 1; 349 curkse->k_sigseqno++; 350 SIGADDSET(curthread->sigpend, sig); 351 /* 352 * If the kse is on the way to idle itself, but 353 * we have signal ready, we should prevent it 354 * to sleep, kernel will latch the wakeup request, 355 * so kse_release will return from kernel immediately. 356 */ 357 if (KSE_IS_IDLE(curkse)) 358 kse_wakeup(&curkse->k_mbx); 359 return; |
261 } | 360 } |
361 362 /* It is now safe to invoke signal handler */ 363 err_save = curthread->error; 364 timeout_save = curthread->timeout; 365 intr_save = curthread->interrupted; 366 /* Get a fresh copy of signal mask from kernel, for thread dump only */ 367 __sys_sigprocmask(SIG_SETMASK, NULL, &curthread->sigmask); 368 _kse_critical_enter(); 369 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 370 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 371 sa_flags = _thread_sigact[sig - 1].sa_flags & SA_SIGINFO; 372 if (sa_flags & SA_RESETHAND) { 373 act.sa_handler = SIG_DFL; 374 act.sa_flags = SA_RESTART; 375 SIGEMPTYSET(act.sa_mask); 376 __sys_sigaction(sig, &act, NULL); 377 __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); 378 } 379 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 380 _kse_critical_leave(&curthread->tmbx); 381 382 /* Now invoke real handler */ 383 if (((__sighandler_t *)sigfunc != SIG_DFL) && 384 ((__sighandler_t *)sigfunc != SIG_IGN) && 385 (sigfunc != (__siginfohandler_t *)_thr_sig_handler)) { 386 if ((sa_flags & SA_SIGINFO) != 0 || info == NULL) 387 (*(sigfunc))(sig, info, ucp); 388 else 389 (*(sigfunc))(sig, (siginfo_t*)(intptr_t)info->si_code, 390 ucp); 391 } else { 392 if ((__sighandler_t *)sigfunc == SIG_DFL) { 393 if (sigprop(sig) & SA_KILL) 394 kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); 395#ifdef NOTYET 396 else if (sigprop(sig) & SA_STOP) 397 kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, sig); 398#endif 399 } 400 } 401 curthread->error = err_save; 402 curthread->timeout = timeout_save; 403 curthread->interrupted = intr_save; 404 _kse_critical_enter(); 405 curthread->sigmask = ucp->uc_sigmask; 406 _kse_critical_leave(&curthread->tmbx); 407 DBG_MSG("<<< _thr_sig_handler(%d)\n", sig); |
|
262} 263 264/* Must be called with signal lock and schedule lock held in order */ 265static void 266thr_sig_invoke_handler(struct pthread *curthread, int sig, siginfo_t *info, 267 ucontext_t *ucp) 268{ 269 void (*sigfunc)(int, siginfo_t *, void *); --- 17 unchanged lines hidden (view full) --- 287 */ 288 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 289 sa_flags = _thread_sigact[sig - 1].sa_flags & SA_SIGINFO; 290 sigmask = curthread->sigmask; 291 SIGSETOR(curthread->sigmask, _thread_sigact[sig - 1].sa_mask); 292 if (!(sa_flags & (SA_NODEFER | SA_RESETHAND))) 293 SIGADDSET(curthread->sigmask, sig); 294 if ((sig != SIGILL) && (sa_flags & SA_RESETHAND)) { | 408} 409 410/* Must be called with signal lock and schedule lock held in order */ 411static void 412thr_sig_invoke_handler(struct pthread *curthread, int sig, siginfo_t *info, 413 ucontext_t *ucp) 414{ 415 void (*sigfunc)(int, siginfo_t *, void *); --- 17 unchanged lines hidden (view full) --- 433 */ 434 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 435 sa_flags = _thread_sigact[sig - 1].sa_flags & SA_SIGINFO; 436 sigmask = curthread->sigmask; 437 SIGSETOR(curthread->sigmask, _thread_sigact[sig - 1].sa_mask); 438 if (!(sa_flags & (SA_NODEFER | SA_RESETHAND))) 439 SIGADDSET(curthread->sigmask, sig); 440 if ((sig != SIGILL) && (sa_flags & SA_RESETHAND)) { |
295 if (_thread_dfl_count[sig - 1] == 0) { 296 act.sa_handler = SIG_DFL; 297 act.sa_flags = SA_RESTART; 298 SIGEMPTYSET(act.sa_mask); 299 __sys_sigaction(sig, &act, NULL); 300 __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); 301 } | 441 act.sa_handler = SIG_DFL; 442 act.sa_flags = SA_RESTART; 443 SIGEMPTYSET(act.sa_mask); 444 __sys_sigaction(sig, &act, NULL); 445 __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); |
302 } 303 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 304 KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); 305 _kse_critical_leave(&curthread->tmbx); | 446 } 447 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 448 KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); 449 _kse_critical_leave(&curthread->tmbx); |
450 /* 451 * We are processing buffered signals, synchronize working 452 * signal mask into kernel. 453 */ 454 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 455 __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); |
|
306 ucp->uc_sigmask = sigmask; | 456 ucp->uc_sigmask = sigmask; |
307 | |
308 if (((__sighandler_t *)sigfunc != SIG_DFL) && 309 ((__sighandler_t *)sigfunc != SIG_IGN)) { 310 if ((sa_flags & SA_SIGINFO) != 0 || info == NULL) 311 (*(sigfunc))(sig, info, ucp); 312 else 313 (*(sigfunc))(sig, (siginfo_t*)(intptr_t)info->si_code, 314 ucp); 315 } else { | 457 if (((__sighandler_t *)sigfunc != SIG_DFL) && 458 ((__sighandler_t *)sigfunc != SIG_IGN)) { 459 if ((sa_flags & SA_SIGINFO) != 0 || info == NULL) 460 (*(sigfunc))(sig, info, ucp); 461 else 462 (*(sigfunc))(sig, (siginfo_t*)(intptr_t)info->si_code, 463 ucp); 464 } else { |
316 /* XXX 317 * TODO: exit process if signal would kill it. 318 */ 319#ifdef NOTYET | 465 if ((__sighandler_t *)sigfunc == SIG_DFL) { |
320 if (sigprop(sig) & SA_KILL) | 466 if (sigprop(sig) & SA_KILL) |
321 kse_sigexit(sig); | 467 kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); 468#ifdef NOTYET 469 else if (sigprop(sig) & SA_STOP) 470 kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, sig); |
322#endif | 471#endif |
472 } |
|
323 } | 473 } |
474 |
|
324 _kse_critical_enter(); 325 /* Don't trust after critical leave/enter */ 326 curkse = _get_curkse(); | 475 _kse_critical_enter(); 476 /* Don't trust after critical leave/enter */ 477 curkse = _get_curkse(); |
327 KSE_SCHED_LOCK(curkse, curkse->k_kseg); 328 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); | 478 |
329 /* 330 * Restore the thread's signal mask. 331 */ 332 curthread->sigmask = ucp->uc_sigmask; | 479 /* 480 * Restore the thread's signal mask. 481 */ 482 curthread->sigmask = ucp->uc_sigmask; |
333 | 483 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 484 __sys_sigprocmask(SIG_SETMASK, &ucp->uc_sigmask, NULL); 485 KSE_SCHED_LOCK(curkse, curkse->k_kseg); 486 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 487 |
334 DBG_MSG("Got signal %d, handler returned %p\n", sig, curthread); 335} 336 337int 338_thr_getprocsig(int sig, siginfo_t *siginfo) 339{ 340 kse_critical_t crit; 341 struct kse *curkse; --- 18 unchanged lines hidden (view full) --- 360 sigset_t sigset; 361 struct timespec ts; 362 363 /* try to retrieve signal from kernel */ 364 SIGEMPTYSET(sigset); 365 SIGADDSET(sigset, sig); 366 ts.tv_sec = 0; 367 ts.tv_nsec = 0; | 488 DBG_MSG("Got signal %d, handler returned %p\n", sig, curthread); 489} 490 491int 492_thr_getprocsig(int sig, siginfo_t *siginfo) 493{ 494 kse_critical_t crit; 495 struct kse *curkse; --- 18 unchanged lines hidden (view full) --- 514 sigset_t sigset; 515 struct timespec ts; 516 517 /* try to retrieve signal from kernel */ 518 SIGEMPTYSET(sigset); 519 SIGADDSET(sigset, sig); 520 ts.tv_sec = 0; 521 ts.tv_nsec = 0; |
368 if (__sys_sigtimedwait(&sigset, siginfo, &ts) > 0) { 369 SIGDELSET(_thr_proc_sigpending, sig); | 522 SIGDELSET(_thr_proc_sigpending, sig); 523 if (__sys_sigtimedwait(&sigset, siginfo, &ts) > 0) |
370 return (sig); | 524 return (sig); |
371 } | |
372 return (0); 373} 374 | 525 return (0); 526} 527 |
528#ifndef SYSTEM_SCOPE_ONLY |
|
375/* 376 * Find a thread that can handle the signal. This must be called 377 * with upcalls disabled. 378 */ 379struct pthread * 380thr_sig_find(struct kse *curkse, int sig, siginfo_t *info) 381{ 382 struct pthread *pthread; 383 struct pthread *suspended_thread, *signaled_thread; | 529/* 530 * Find a thread that can handle the signal. This must be called 531 * with upcalls disabled. 532 */ 533struct pthread * 534thr_sig_find(struct kse *curkse, int sig, siginfo_t *info) 535{ 536 struct pthread *pthread; 537 struct pthread *suspended_thread, *signaled_thread; |
538 __siginfohandler_t *sigfunc; |
|
384 siginfo_t si; 385 386 DBG_MSG("Looking for thread to handle signal %d\n", sig); 387 | 539 siginfo_t si; 540 541 DBG_MSG("Looking for thread to handle signal %d\n", sig); 542 |
388 /* Check if the signal requires a dump of thread information: */ 389 if (sig == SIGINFO) { 390 /* Dump thread information to file: */ 391 _thread_dump_info(); 392 } | |
393 /* 394 * Enter a loop to look for threads that have the signal 395 * unmasked. POSIX specifies that a thread in a sigwait 396 * will get the signal over any other threads. Second 397 * preference will be threads in in a sigsuspend. Third 398 * preference will be the current thread. If none of the 399 * above, then the signal is delivered to the first thread 400 * that is found. Note that if a custom handler is not 401 * installed, the signal only affects threads in sigwait. 402 */ 403 suspended_thread = NULL; 404 signaled_thread = NULL; 405 406 KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); 407 TAILQ_FOREACH(pthread, &_thread_list, tle) { 408 if (pthread == _thr_sig_daemon) 409 continue; | 543 /* 544 * Enter a loop to look for threads that have the signal 545 * unmasked. POSIX specifies that a thread in a sigwait 546 * will get the signal over any other threads. Second 547 * preference will be threads in in a sigsuspend. Third 548 * preference will be the current thread. If none of the 549 * above, then the signal is delivered to the first thread 550 * that is found. Note that if a custom handler is not 551 * installed, the signal only affects threads in sigwait. 552 */ 553 suspended_thread = NULL; 554 signaled_thread = NULL; 555 556 KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); 557 TAILQ_FOREACH(pthread, &_thread_list, tle) { 558 if (pthread == _thr_sig_daemon) 559 continue; |
410#ifdef NOTYET | |
411 /* Signal delivering to bound thread is done by kernel */ 412 if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 413 continue; | 560 /* Signal delivering to bound thread is done by kernel */ 561 if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 562 continue; |
414#endif 415 | |
416 /* Take the scheduling lock. */ 417 KSE_SCHED_LOCK(curkse, pthread->kseg); 418 if ((pthread->state == PS_DEAD) || 419 (pthread->state == PS_DEADLOCK) || 420 THR_IS_EXITING(pthread) || 421 THR_IS_SUSPENDED(pthread)) { 422 ; /* Skip this thread. */ 423 } else if (pthread->state == PS_SIGWAIT && --- 22 unchanged lines hidden (view full) --- 446 * 447 * Do not attempt to deliver this signal 448 * to other threads and do not add the signal 449 * to the process pending set. 450 */ 451 KSE_LOCK_RELEASE(curkse, &_thread_list_lock); 452 return (NULL); 453 } else if (!SIGISMEMBER(pthread->sigmask, sig) || | 563 /* Take the scheduling lock. */ 564 KSE_SCHED_LOCK(curkse, pthread->kseg); 565 if ((pthread->state == PS_DEAD) || 566 (pthread->state == PS_DEADLOCK) || 567 THR_IS_EXITING(pthread) || 568 THR_IS_SUSPENDED(pthread)) { 569 ; /* Skip this thread. */ 570 } else if (pthread->state == PS_SIGWAIT && --- 22 unchanged lines hidden (view full) --- 593 * 594 * Do not attempt to deliver this signal 595 * to other threads and do not add the signal 596 * to the process pending set. 597 */ 598 KSE_LOCK_RELEASE(curkse, &_thread_list_lock); 599 return (NULL); 600 } else if (!SIGISMEMBER(pthread->sigmask, sig) || |
454 (!SIGISMEMBER(pthread->oldsigmask, sig) && 455 pthread->state == PS_SIGWAIT)) { | 601 (!SIGISMEMBER(pthread->oldsigmask, sig) && 602 pthread->state == PS_SIGWAIT)) { 603 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 604 if ((__sighandler_t *)sigfunc == SIG_DFL) { 605 if (sigprop(sig) & SA_KILL) { 606 kse_thr_interrupt(NULL, 607 KSE_INTR_SIGEXIT, sig); 608 /* Never reach */ 609 } 610 } |
456 if (pthread->state == PS_SIGSUSPEND) { 457 if (suspended_thread == NULL) { 458 suspended_thread = pthread; 459 suspended_thread->refcount++; 460 } 461 } else if (signaled_thread == NULL) { 462 signaled_thread = pthread; 463 signaled_thread->refcount++; --- 9 unchanged lines hidden (view full) --- 473 _thr_ref_delete(NULL, signaled_thread); 474 } else if (signaled_thread) { 475 pthread = signaled_thread; 476 } else { 477 pthread = NULL; 478 } 479 return (pthread); 480} | 611 if (pthread->state == PS_SIGSUSPEND) { 612 if (suspended_thread == NULL) { 613 suspended_thread = pthread; 614 suspended_thread->refcount++; 615 } 616 } else if (signaled_thread == NULL) { 617 signaled_thread = pthread; 618 signaled_thread->refcount++; --- 9 unchanged lines hidden (view full) --- 628 _thr_ref_delete(NULL, signaled_thread); 629 } else if (signaled_thread) { 630 pthread = signaled_thread; 631 } else { 632 pthread = NULL; 633 } 634 return (pthread); 635} |
636#endif /* ! SYSTEM_SCOPE_ONLY */ |
|
481 482static void 483build_siginfo(siginfo_t *info, int signo) 484{ 485 bzero(info, sizeof(*info)); 486 info->si_signo = signo; 487 info->si_pid = _thr_pid; 488} --- 7 unchanged lines hidden (view full) --- 496 struct pthread_sigframe *psf) 497{ 498 int interrupted = curthread->interrupted; 499 int timeout = curthread->timeout; 500 siginfo_t siginfo; 501 int i; 502 kse_critical_t crit; 503 struct kse *curkse; | 637 638static void 639build_siginfo(siginfo_t *info, int signo) 640{ 641 bzero(info, sizeof(*info)); 642 info->si_signo = signo; 643 info->si_pid = _thr_pid; 644} --- 7 unchanged lines hidden (view full) --- 652 struct pthread_sigframe *psf) 653{ 654 int interrupted = curthread->interrupted; 655 int timeout = curthread->timeout; 656 siginfo_t siginfo; 657 int i; 658 kse_critical_t crit; 659 struct kse *curkse; |
660 sigset_t sigmask; |
|
504 | 661 |
505 DBG_MSG(">>> thr_sig_rundown %p\n", curthread); | 662 DBG_MSG(">>> thr_sig_rundown (%p)\n", curthread); |
506 /* Check the threads previous state: */ 507 if ((psf != NULL) && (psf->psf_valid != 0)) { 508 /* 509 * Do a little cleanup handling for those threads in 510 * queues before calling the signal handler. Signals 511 * for these threads are temporarily blocked until 512 * after cleanup handling. 513 */ --- 25 unchanged lines hidden (view full) --- 539 */ 540 crit = _kse_critical_enter(); 541 curkse = _get_curkse(); 542 KSE_SCHED_LOCK(curkse, curkse->k_kseg); 543 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 544 curthread->active_priority &= ~THR_SIGNAL_PRIORITY; 545 546 while (1) { | 663 /* Check the threads previous state: */ 664 if ((psf != NULL) && (psf->psf_valid != 0)) { 665 /* 666 * Do a little cleanup handling for those threads in 667 * queues before calling the signal handler. Signals 668 * for these threads are temporarily blocked until 669 * after cleanup handling. 670 */ --- 25 unchanged lines hidden (view full) --- 696 */ 697 crit = _kse_critical_enter(); 698 curkse = _get_curkse(); 699 KSE_SCHED_LOCK(curkse, curkse->k_kseg); 700 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 701 curthread->active_priority &= ~THR_SIGNAL_PRIORITY; 702 703 while (1) { |
704 /* 705 * For bound thread, we mask all signals and get a fresh 706 * copy of signal mask from kernel 707 */ 708 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { 709 SIGFILLSET(sigmask); 710 __sys_sigprocmask(SIG_SETMASK, &sigmask, 711 &curthread->sigmask); 712 } |
|
547 for (i = 1; i <= _SIG_MAXSIG; i++) { 548 if (SIGISMEMBER(curthread->sigmask, i)) 549 continue; 550 if (SIGISMEMBER(curthread->sigpend, i)) { 551 SIGDELSET(curthread->sigpend, i); 552 siginfo = curthread->siginfo[i-1]; 553 break; 554 } | 713 for (i = 1; i <= _SIG_MAXSIG; i++) { 714 if (SIGISMEMBER(curthread->sigmask, i)) 715 continue; 716 if (SIGISMEMBER(curthread->sigpend, i)) { 717 SIGDELSET(curthread->sigpend, i); 718 siginfo = curthread->siginfo[i-1]; 719 break; 720 } |
555 if (SIGISMEMBER(_thr_proc_sigpending, i)) { | 721 if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 722 && SIGISMEMBER(_thr_proc_sigpending, i)) { |
556 if (_thr_getprocsig_unlocked(i, &siginfo)) 557 break; 558 } 559 } 560 if (i <= _SIG_MAXSIG) 561 thr_sig_invoke_handler(curthread, i, &siginfo, ucp); 562 else 563 break; 564 } 565 566 if (psf != NULL && psf->psf_valid != 0) 567 thr_sigframe_restore(curthread, psf); 568 curkse = _get_curkse(); 569 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 570 KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); | 723 if (_thr_getprocsig_unlocked(i, &siginfo)) 724 break; 725 } 726 } 727 if (i <= _SIG_MAXSIG) 728 thr_sig_invoke_handler(curthread, i, &siginfo, ucp); 729 else 730 break; 731 } 732 733 if (psf != NULL && psf->psf_valid != 0) 734 thr_sigframe_restore(curthread, psf); 735 curkse = _get_curkse(); 736 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 737 KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); |
738 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 739 __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); |
|
571 _kse_critical_leave(&curthread->tmbx); 572 573 curthread->interrupted = interrupted; 574 curthread->timeout = timeout; 575 | 740 _kse_critical_leave(&curthread->tmbx); 741 742 curthread->interrupted = interrupted; 743 curthread->timeout = timeout; 744 |
576 DBG_MSG("<<< thr_sig_rundown %p\n", curthread); | 745 DBG_MSG("<<< thr_sig_rundown (%p)\n", curthread); |
577} 578 579/* 580 * This checks pending signals for the current thread. It should be 581 * called whenever a thread changes its signal mask. Note that this 582 * is called from a thread (using its stack). 583 * 584 * XXX - We might want to just check to see if there are pending --- 13 unchanged lines hidden (view full) --- 598 THR_GETCONTEXT(&uc); 599 if (once == 0) { 600 once = 1; 601 curthread->check_pending = 0; 602 _thr_sig_rundown(curthread, &uc, NULL); 603 } 604} 605 | 746} 747 748/* 749 * This checks pending signals for the current thread. It should be 750 * called whenever a thread changes its signal mask. Note that this 751 * is called from a thread (using its stack). 752 * 753 * XXX - We might want to just check to see if there are pending --- 13 unchanged lines hidden (view full) --- 767 THR_GETCONTEXT(&uc); 768 if (once == 0) { 769 once = 1; 770 curthread->check_pending = 0; 771 _thr_sig_rundown(curthread, &uc, NULL); 772 } 773} 774 |
775#ifndef SYSTEM_SCOPE_ONLY |
|
606/* 607 * This must be called with upcalls disabled. 608 */ 609static void 610handle_special_signals(struct kse *curkse, int sig) 611{ 612 switch (sig) { 613 /* --- 12 unchanged lines hidden (view full) --- 626 SIGDELSET(_thr_proc_sigpending, SIGTSTP); 627 SIGDELSET(_thr_proc_sigpending, SIGTTIN); 628 SIGDELSET(_thr_proc_sigpending, SIGTTOU); 629 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 630 default: 631 break; 632 } 633} | 776/* 777 * This must be called with upcalls disabled. 778 */ 779static void 780handle_special_signals(struct kse *curkse, int sig) 781{ 782 switch (sig) { 783 /* --- 12 unchanged lines hidden (view full) --- 796 SIGDELSET(_thr_proc_sigpending, SIGTSTP); 797 SIGDELSET(_thr_proc_sigpending, SIGTTIN); 798 SIGDELSET(_thr_proc_sigpending, SIGTTOU); 799 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 800 default: 801 break; 802 } 803} |
804#endif /* ! SYSTEM_SCOPE_ONLY */ |
|
634 635/* 636 * Perform thread specific actions in response to a signal. 637 * This function is only called if there is a handler installed 638 * for the signal, and if the target thread has the signal 639 * unmasked. 640 * 641 * This must be called with the thread's scheduling lock held. 642 */ 643void 644_thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info) 645{ 646 int restart; 647 int suppress_handler = 0; 648 int fromproc = 0; 649 struct pthread *curthread = _get_curthread(); 650 struct kse *curkse; 651 siginfo_t siginfo; 652 | 805 806/* 807 * Perform thread specific actions in response to a signal. 808 * This function is only called if there is a handler installed 809 * for the signal, and if the target thread has the signal 810 * unmasked. 811 * 812 * This must be called with the thread's scheduling lock held. 813 */ 814void 815_thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info) 816{ 817 int restart; 818 int suppress_handler = 0; 819 int fromproc = 0; 820 struct pthread *curthread = _get_curthread(); 821 struct kse *curkse; 822 siginfo_t siginfo; 823 |
653 DBG_MSG(">>> _thr_sig_add\n"); | 824 DBG_MSG(">>> _thr_sig_add %p (%d)\n", pthread, sig); |
654 655 curkse = _get_curkse(); 656 restart = _thread_sigact[sig - 1].sa_flags & SA_RESTART; 657 fromproc = (curthread == _thr_sig_daemon); 658 659 if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK || 660 pthread->state == PS_STATE_MAX) 661 return; /* return false */ 662 | 825 826 curkse = _get_curkse(); 827 restart = _thread_sigact[sig - 1].sa_flags & SA_RESTART; 828 fromproc = (curthread == _thr_sig_daemon); 829 830 if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK || 831 pthread->state == PS_STATE_MAX) 832 return; /* return false */ 833 |
663#ifdef NOTYET 664 if ((pthread->attrs.flags & PTHREAD_SCOPE_SYSTEM) != 0) { 665 if (!fromproc) 666 kse_thr_interrupt(&pthread->tmbx, 0, sig); | 834 if ((pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && 835 (curthread != pthread)) { 836 PANIC("Please use _thr_send_sig for bound thread"); |
667 return; 668 } | 837 return; 838 } |
669#endif | |
670 671 if (pthread->curframe == NULL || 672 (pthread->state != PS_SIGWAIT && 673 SIGISMEMBER(pthread->sigmask, sig)) || 674 THR_IN_CRITICAL(pthread)) { 675 /* thread is running or signal was being masked */ 676 if (!fromproc) { 677 SIGADDSET(pthread->sigpend, sig); --- 4 unchanged lines hidden (view full) --- 682 sizeof(*info)); 683 } else { 684 if (!_thr_getprocsig(sig, &pthread->siginfo[sig-1])) 685 return; 686 SIGADDSET(pthread->sigpend, sig); 687 } 688 if (!SIGISMEMBER(pthread->sigmask, sig)) { 689 pthread->check_pending = 1; | 839 840 if (pthread->curframe == NULL || 841 (pthread->state != PS_SIGWAIT && 842 SIGISMEMBER(pthread->sigmask, sig)) || 843 THR_IN_CRITICAL(pthread)) { 844 /* thread is running or signal was being masked */ 845 if (!fromproc) { 846 SIGADDSET(pthread->sigpend, sig); --- 4 unchanged lines hidden (view full) --- 851 sizeof(*info)); 852 } else { 853 if (!_thr_getprocsig(sig, &pthread->siginfo[sig-1])) 854 return; 855 SIGADDSET(pthread->sigpend, sig); 856 } 857 if (!SIGISMEMBER(pthread->sigmask, sig)) { 858 pthread->check_pending = 1; |
690 if (pthread->blocked != 0 && !THR_IN_CRITICAL(pthread)) | 859 if (!(pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && 860 (pthread->blocked != 0) && 861 !THR_IN_CRITICAL(pthread)) |
691 kse_thr_interrupt(&pthread->tmbx, | 862 kse_thr_interrupt(&pthread->tmbx, |
692 restart ? -2 : -1); | 863 restart ? KSE_INTR_RESTART : KSE_INTR_INTERRUPT, 0); |
693 } 694 } 695 else { 696 /* if process signal not exists, just return */ 697 if (fromproc) { 698 if (!_thr_getprocsig(sig, &siginfo)) 699 return; 700 info = &siginfo; --- 95 unchanged lines hidden (view full) --- 796 if (pthread->flags & THR_FLAGS_IN_RUNQ) 797 THR_RUNQ_REMOVE(pthread); 798 pthread->active_priority |= THR_SIGNAL_PRIORITY; 799 _thr_setrunnable_unlocked(pthread); 800 } else { 801 pthread->check_pending = 1; 802 } 803 } | 864 } 865 } 866 else { 867 /* if process signal not exists, just return */ 868 if (fromproc) { 869 if (!_thr_getprocsig(sig, &siginfo)) 870 return; 871 info = &siginfo; --- 95 unchanged lines hidden (view full) --- 967 if (pthread->flags & THR_FLAGS_IN_RUNQ) 968 THR_RUNQ_REMOVE(pthread); 969 pthread->active_priority |= THR_SIGNAL_PRIORITY; 970 _thr_setrunnable_unlocked(pthread); 971 } else { 972 pthread->check_pending = 1; 973 } 974 } |
804 805 DBG_MSG("<<< _thr_sig_add\n"); | |
806} 807 | 975} 976 |
808static void 809thr_sig_check_state(struct pthread *pthread, int sig) 810{ 811 /* 812 * Process according to thread state: 813 */ 814 switch (pthread->state) { 815 /* 816 * States which do not change when a signal is trapped: 817 */ 818 case PS_RUNNING: 819 case PS_LOCKWAIT: 820 case PS_MUTEX_WAIT: 821 case PS_COND_WAIT: 822 case PS_JOIN: 823 case PS_SUSPENDED: 824 case PS_DEAD: 825 case PS_DEADLOCK: 826 case PS_STATE_MAX: 827 break; 828 829 case PS_SIGWAIT: 830 build_siginfo(&pthread->siginfo[sig-1], sig); 831 /* Wake up the thread if the signal is blocked. */ 832 if (!SIGISMEMBER(pthread->sigmask, sig)) { 833 /* Return the signal number: */ 834 *(pthread->data.sigwaitinfo) = pthread->siginfo[sig-1]; 835 pthread->sigmask = pthread->oldsigmask; 836 /* Change the state of the thread to run: */ 837 _thr_setrunnable_unlocked(pthread); 838 } else { 839 /* Increment the pending signal count. */ 840 SIGADDSET(pthread->sigpend, sig); 841 if (!SIGISMEMBER(pthread->oldsigmask, sig)) { 842 pthread->check_pending = 1; 843 pthread->interrupted = 1; 844 pthread->sigmask = pthread->oldsigmask; 845 _thr_setrunnable_unlocked(pthread); 846 } 847 } 848 break; 849 850 case PS_SIGSUSPEND: 851 case PS_SLEEP_WAIT: 852 /* 853 * Remove the thread from the wait queue and make it 854 * runnable: 855 */ 856 _thr_setrunnable_unlocked(pthread); 857 858 /* Flag the operation as interrupted: */ 859 pthread->interrupted = 1; 860 break; 861 } 862} 863 | |
864/* 865 * Send a signal to a specific thread (ala pthread_kill): 866 */ 867void 868_thr_sig_send(struct pthread *pthread, int sig) 869{ 870 struct pthread *curthread = _get_curthread(); 871 | 977/* 978 * Send a signal to a specific thread (ala pthread_kill): 979 */ 980void 981_thr_sig_send(struct pthread *pthread, int sig) 982{ 983 struct pthread *curthread = _get_curthread(); 984 |
872#ifdef NOTYET 873 if ((pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) { 874 kse_thr_interrupt(&pthread->tmbx, sig); | 985 if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { 986 kse_thr_interrupt(&pthread->tmbx, KSE_INTR_SENDSIG, sig); |
875 return; 876 } | 987 return; 988 } |
877#endif | 989 |
878 /* Lock the scheduling queue of the target thread. */ 879 THR_SCHED_LOCK(curthread, pthread); | 990 /* Lock the scheduling queue of the target thread. */ 991 THR_SCHED_LOCK(curthread, pthread); |
880 881 /* Check for signals whose actions are SIG_DFL: */ 882 if (_thread_sigact[sig - 1].sa_handler == SIG_DFL) { 883 /* 884 * Check to see if a temporary signal handler is 885 * installed for sigwaiters: 886 */ 887 if (_thread_dfl_count[sig - 1] == 0) { 888 /* 889 * Deliver the signal to the process if a handler 890 * is not installed: 891 */ 892 THR_SCHED_UNLOCK(curthread, pthread); 893 kill(getpid(), sig); 894 THR_SCHED_LOCK(curthread, pthread); 895 } 896 /* 897 * Assuming we're still running after the above kill(), 898 * make any necessary state changes to the thread: 899 */ 900 thr_sig_check_state(pthread, sig); 901 THR_SCHED_UNLOCK(curthread, pthread); 902 } 903 /* 904 * Check that the signal is not being ignored: 905 */ 906 else if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) { | 992 if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) { |
907 _thr_sig_add(pthread, sig, NULL); 908 THR_SCHED_UNLOCK(curthread, pthread); 909 /* XXX 910 * If thread sent signal to itself, check signals now. 911 * It is not really needed, _kse_critical_leave should 912 * have already checked signals. 913 */ 914 if (pthread == curthread && curthread->check_pending) --- 45 unchanged lines hidden (view full) --- 960 psf->psf_wakeup_time = thread->wakeup_time; 961} 962 963void 964_thr_signal_init(void) 965{ 966 sigset_t sigset; 967 struct sigaction act; | 993 _thr_sig_add(pthread, sig, NULL); 994 THR_SCHED_UNLOCK(curthread, pthread); 995 /* XXX 996 * If thread sent signal to itself, check signals now. 997 * It is not really needed, _kse_critical_leave should 998 * have already checked signals. 999 */ 1000 if (pthread == curthread && curthread->check_pending) --- 45 unchanged lines hidden (view full) --- 1046 psf->psf_wakeup_time = thread->wakeup_time; 1047} 1048 1049void 1050_thr_signal_init(void) 1051{ 1052 sigset_t sigset; 1053 struct sigaction act; |
1054 __siginfohandler_t *sigfunc; |
|
968 int i; 969 970 SIGFILLSET(sigset); 971 __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); 972 /* Enter a loop to get the existing signal status: */ 973 for (i = 1; i <= _SIG_MAXSIG; i++) { 974 /* Check for signals which cannot be trapped: */ 975 if (i == SIGKILL || i == SIGSTOP) { 976 } 977 978 /* Get the signal handler details: */ 979 else if (__sys_sigaction(i, NULL, 980 &_thread_sigact[i - 1]) != 0) { 981 /* 982 * Abort this process if signal 983 * initialisation fails: 984 */ 985 PANIC("Cannot read signal handler info"); 986 } | 1055 int i; 1056 1057 SIGFILLSET(sigset); 1058 __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); 1059 /* Enter a loop to get the existing signal status: */ 1060 for (i = 1; i <= _SIG_MAXSIG; i++) { 1061 /* Check for signals which cannot be trapped: */ 1062 if (i == SIGKILL || i == SIGSTOP) { 1063 } 1064 1065 /* Get the signal handler details: */ 1066 else if (__sys_sigaction(i, NULL, 1067 &_thread_sigact[i - 1]) != 0) { 1068 /* 1069 * Abort this process if signal 1070 * initialisation fails: 1071 */ 1072 PANIC("Cannot read signal handler info"); 1073 } |
1074 /* Intall wrapper if handler was set */ 1075 sigfunc = _thread_sigact[i - 1].sa_sigaction; 1076 if (((__sighandler_t *)sigfunc) != SIG_DFL && 1077 ((__sighandler_t *)sigfunc) != SIG_IGN) { 1078 act = _thread_sigact[i - 1]; 1079 act.sa_flags |= SA_SIGINFO; 1080 act.sa_sigaction = (__siginfohandler_t *)_thr_sig_handler; 1081 __sys_sigaction(i, &act, NULL); 1082 } |
|
987 } 988 /* 989 * Install the signal handler for SIGINFO. It isn't 990 * really needed, but it is nice to have for debugging 991 * purposes. 992 */ 993 _thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART; 994 SIGEMPTYSET(act.sa_mask); 995 act.sa_flags = SA_SIGINFO | SA_RESTART; 996 act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler; 997 if (__sys_sigaction(SIGINFO, &act, NULL) != 0) { 998 /* 999 * Abort this process if signal initialisation fails: 1000 */ 1001 PANIC("Cannot initialize signal handler"); 1002 } | 1083 } 1084 /* 1085 * Install the signal handler for SIGINFO. It isn't 1086 * really needed, but it is nice to have for debugging 1087 * purposes. 1088 */ 1089 _thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART; 1090 SIGEMPTYSET(act.sa_mask); 1091 act.sa_flags = SA_SIGINFO | SA_RESTART; 1092 act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler; 1093 if (__sys_sigaction(SIGINFO, &act, NULL) != 0) { 1094 /* 1095 * Abort this process if signal initialisation fails: 1096 */ 1097 PANIC("Cannot initialize signal handler"); 1098 } |
1099#ifdef SYSTEM_SCOPE_ONLY 1100 __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, NULL); 1101#endif |
|
1003} 1004 1005void 1006_thr_signal_deinit(void) 1007{ 1008 struct pthread *curthread = _get_curthread(); 1009 sigset_t tmpmask; 1010 int i; --- 22 unchanged lines hidden --- | 1102} 1103 1104void 1105_thr_signal_deinit(void) 1106{ 1107 struct pthread *curthread = _get_curthread(); 1108 sigset_t tmpmask; 1109 int i; --- 22 unchanged lines hidden --- |