thr_sig.c (209933) | thr_sig.c (211524) |
---|---|
1/* 2 * Copyright (c) 2005, David Xu <davidxu@freebsd.org> 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 --- 9 unchanged lines hidden (view full) --- 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * | 1/* 2 * Copyright (c) 2005, David Xu <davidxu@freebsd.org> 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 --- 9 unchanged lines hidden (view full) --- 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/lib/libthr/thread/thr_sig.c 209933 2010-07-12 10:15:33Z kib $ | 26 * $FreeBSD: head/lib/libthr/thread/thr_sig.c 211524 2010-08-20 05:15:39Z davidxu $ |
27 */ 28 29#include "namespace.h" 30#include <sys/param.h> 31#include <sys/types.h> 32#include <sys/signalvar.h> 33#include <signal.h> 34#include <errno.h> --- 27 unchanged lines hidden (view full) --- 62 63 64static void 65sigcancel_handler(int sig __unused, 66 siginfo_t *info __unused, ucontext_t *ucp __unused) 67{ 68 struct pthread *curthread = _get_curthread(); 69 | 27 */ 28 29#include "namespace.h" 30#include <sys/param.h> 31#include <sys/types.h> 32#include <sys/signalvar.h> 33#include <signal.h> 34#include <errno.h> --- 27 unchanged lines hidden (view full) --- 62 63 64static void 65sigcancel_handler(int sig __unused, 66 siginfo_t *info __unused, ucontext_t *ucp __unused) 67{ 68 struct pthread *curthread = _get_curthread(); 69 |
70 if (curthread->cancel_defer && curthread->cancel_pending) 71 thr_wake(curthread->tid); | |
72 curthread->in_sigcancel_handler++; 73 _thr_ast(curthread); 74 curthread->in_sigcancel_handler--; 75} 76 77void 78_thr_ast(struct pthread *curthread) 79{ | 70 curthread->in_sigcancel_handler++; 71 _thr_ast(curthread); 72 curthread->in_sigcancel_handler--; 73} 74 75void 76_thr_ast(struct pthread *curthread) 77{ |
80 if (!THR_IN_CRITICAL(curthread)) { 81 _thr_testcancel(curthread); 82 if (__predict_false((curthread->flags & 83 (THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED)) 84 == THR_FLAGS_NEED_SUSPEND)) 85 _thr_suspend_check(curthread); | 78 79 if (THR_IN_CRITICAL(curthread)) 80 return; 81 82 if (curthread->cancel_pending && curthread->cancel_enable 83 && !curthread->cancelling) { 84 if (curthread->cancel_async) { 85 /* 86 * asynchronous cancellation mode, act upon 87 * immediately. 88 */ 89 _pthread_exit(PTHREAD_CANCELED); 90 } else { 91 /* 92 * Otherwise, we are in defer mode, and we are at 93 * cancel point, tell kernel to not block the current 94 * thread on next cancelable system call. 95 * 96 * There are two cases we should call thr_wake() to 97 * turn on TDP_WAKEUP in kernel: 98 * 1) we are going to call a cancelable system call, 99 * non-zero cancel_point means we are already in 100 * cancelable state, next system call is cancelable. 101 * 2) because _thr_ast() may be called by 102 * THR_CRITICAL_LEAVE() which is used by rtld rwlock 103 * and any libthr internal locks, when rtld rwlock 104 * is used, it is mostly caused my an unresolved PLT. 105 * those routines may clear the TDP_WAKEUP flag by 106 * invoking some system calls, in those cases, we 107 * also should reenable the flag. 108 */ 109 if (curthread->cancel_point) { 110 if (curthread->cancel_defer) 111 thr_wake(curthread->tid); 112 else 113 _pthread_exit(PTHREAD_CANCELED); 114 } 115 } |
86 } | 116 } |
117 118 if (__predict_false((curthread->flags & 119 (THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED)) 120 == THR_FLAGS_NEED_SUSPEND)) 121 _thr_suspend_check(curthread); |
|
87} 88 89void 90_thr_suspend_check(struct pthread *curthread) 91{ 92 uint32_t cycle; 93 int err; 94 --- 196 unchanged lines hidden (view full) --- 291 SIGDELSET(newset, SIGCANCEL); 292 pset = &newset; 293 } else 294 pset = set; 295 ret = __sys_sigtimedwait(pset, info, timeout); 296 return (ret); 297} 298 | 122} 123 124void 125_thr_suspend_check(struct pthread *curthread) 126{ 127 uint32_t cycle; 128 int err; 129 --- 196 unchanged lines hidden (view full) --- 326 SIGDELSET(newset, SIGCANCEL); 327 pset = &newset; 328 } else 329 pset = set; 330 ret = __sys_sigtimedwait(pset, info, timeout); 331 return (ret); 332} 333 |
334/* 335 * Cancellation behavior: 336 * Thread may be canceled at start, if thread got signal, 337 * it is not canceled. 338 */ |
|
299int 300__sigtimedwait(const sigset_t *set, siginfo_t *info, 301 const struct timespec * timeout) 302{ 303 struct pthread *curthread = _get_curthread(); 304 sigset_t newset; 305 const sigset_t *pset; 306 int ret; 307 308 if (SIGISMEMBER(*set, SIGCANCEL)) { 309 newset = *set; 310 SIGDELSET(newset, SIGCANCEL); 311 pset = &newset; 312 } else 313 pset = set; | 339int 340__sigtimedwait(const sigset_t *set, siginfo_t *info, 341 const struct timespec * timeout) 342{ 343 struct pthread *curthread = _get_curthread(); 344 sigset_t newset; 345 const sigset_t *pset; 346 int ret; 347 348 if (SIGISMEMBER(*set, SIGCANCEL)) { 349 newset = *set; 350 SIGDELSET(newset, SIGCANCEL); 351 pset = &newset; 352 } else 353 pset = set; |
314 _thr_cancel_enter(curthread); | 354 _thr_cancel_enter_defer(curthread, 1); |
315 ret = __sys_sigtimedwait(pset, info, timeout); | 355 ret = __sys_sigtimedwait(pset, info, timeout); |
316 _thr_cancel_leave(curthread); | 356 _thr_cancel_leave_defer(curthread, (ret == -1)); |
317 return (ret); 318} 319 320int 321_sigwaitinfo(const sigset_t *set, siginfo_t *info) 322{ 323 sigset_t newset; 324 const sigset_t *pset; --- 5 unchanged lines hidden (view full) --- 330 pset = &newset; 331 } else 332 pset = set; 333 334 ret = __sys_sigwaitinfo(pset, info); 335 return (ret); 336} 337 | 357 return (ret); 358} 359 360int 361_sigwaitinfo(const sigset_t *set, siginfo_t *info) 362{ 363 sigset_t newset; 364 const sigset_t *pset; --- 5 unchanged lines hidden (view full) --- 370 pset = &newset; 371 } else 372 pset = set; 373 374 ret = __sys_sigwaitinfo(pset, info); 375 return (ret); 376} 377 |
378/* 379 * Cancellation behavior: 380 * Thread may be canceled at start, if thread got signal, 381 * it is not canceled. 382 */ |
|
338int 339__sigwaitinfo(const sigset_t *set, siginfo_t *info) 340{ 341 struct pthread *curthread = _get_curthread(); 342 sigset_t newset; 343 const sigset_t *pset; 344 int ret; 345 346 if (SIGISMEMBER(*set, SIGCANCEL)) { 347 newset = *set; 348 SIGDELSET(newset, SIGCANCEL); 349 pset = &newset; 350 } else 351 pset = set; 352 | 383int 384__sigwaitinfo(const sigset_t *set, siginfo_t *info) 385{ 386 struct pthread *curthread = _get_curthread(); 387 sigset_t newset; 388 const sigset_t *pset; 389 int ret; 390 391 if (SIGISMEMBER(*set, SIGCANCEL)) { 392 newset = *set; 393 SIGDELSET(newset, SIGCANCEL); 394 pset = &newset; 395 } else 396 pset = set; 397 |
353 _thr_cancel_enter(curthread); | 398 _thr_cancel_enter_defer(curthread, 1); |
354 ret = __sys_sigwaitinfo(pset, info); | 399 ret = __sys_sigwaitinfo(pset, info); |
355 _thr_cancel_leave(curthread); | 400 _thr_cancel_leave_defer(curthread, ret == -1); |
356 return (ret); 357} 358 359int 360_sigwait(const sigset_t *set, int *sig) 361{ 362 sigset_t newset; 363 const sigset_t *pset; --- 5 unchanged lines hidden (view full) --- 369 pset = &newset; 370 } else 371 pset = set; 372 373 ret = __sys_sigwait(pset, sig); 374 return (ret); 375} 376 | 401 return (ret); 402} 403 404int 405_sigwait(const sigset_t *set, int *sig) 406{ 407 sigset_t newset; 408 const sigset_t *pset; --- 5 unchanged lines hidden (view full) --- 414 pset = &newset; 415 } else 416 pset = set; 417 418 ret = __sys_sigwait(pset, sig); 419 return (ret); 420} 421 |
422/* 423 * Cancellation behavior: 424 * Thread may be canceled at start, if thread got signal, 425 * it is not canceled. 426 */ |
|
377int 378__sigwait(const sigset_t *set, int *sig) 379{ 380 struct pthread *curthread = _get_curthread(); 381 sigset_t newset; 382 const sigset_t *pset; 383 int ret; 384 385 if (SIGISMEMBER(*set, SIGCANCEL)) { 386 newset = *set; 387 SIGDELSET(newset, SIGCANCEL); 388 pset = &newset; 389 } else 390 pset = set; 391 | 427int 428__sigwait(const sigset_t *set, int *sig) 429{ 430 struct pthread *curthread = _get_curthread(); 431 sigset_t newset; 432 const sigset_t *pset; 433 int ret; 434 435 if (SIGISMEMBER(*set, SIGCANCEL)) { 436 newset = *set; 437 SIGDELSET(newset, SIGCANCEL); 438 pset = &newset; 439 } else 440 pset = set; 441 |
392 _thr_cancel_enter(curthread); | 442 _thr_cancel_enter_defer(curthread, 1); |
393 ret = __sys_sigwait(pset, sig); | 443 ret = __sys_sigwait(pset, sig); |
394 _thr_cancel_leave(curthread); | 444 _thr_cancel_leave_defer(curthread, (ret != 0)); |
395 return (ret); 396} | 445 return (ret); 446} |