Deleted Added
full compact
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}