2 * Copyright (c) 2005, David Xu <davidxu@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
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.
30 #include "namespace.h"
32 #include "un-namespace.h"
34 #include "thr_private.h"
36 __weak_reference(_pthread_cancel, pthread_cancel);
37 __weak_reference(_pthread_setcancelstate, pthread_setcancelstate);
38 __weak_reference(_pthread_setcanceltype, pthread_setcanceltype);
39 __weak_reference(_pthread_testcancel, pthread_testcancel);
42 testcancel(struct pthread *curthread)
44 if (__predict_false(SHOULD_CANCEL(curthread) &&
45 !THR_IN_CRITICAL(curthread) && curthread->cancel_defer == 0))
46 _pthread_exit(PTHREAD_CANCELED);
50 _thr_testcancel(struct pthread *curthread)
52 testcancel(curthread);
56 _pthread_cancel(pthread_t pthread)
58 struct pthread *curthread = _get_curthread();
62 * POSIX says _pthread_cancel should be async cancellation safe.
63 * _thr_ref_add and _thr_ref_delete will enter and leave critical
64 * region automatically.
66 if ((ret = _thr_ref_add(curthread, pthread, 0)) == 0) {
67 THR_THREAD_LOCK(curthread, pthread);
68 if (!pthread->cancel_pending) {
69 pthread->cancel_pending = 1;
70 if (pthread->cancel_enable)
71 _thr_send_sig(pthread, SIGCANCEL);
73 THR_THREAD_UNLOCK(curthread, pthread);
74 _thr_ref_delete(curthread, pthread);
80 _pthread_setcancelstate(int state, int *oldstate)
82 struct pthread *curthread = _get_curthread();
85 oldval = curthread->cancel_enable;
87 case PTHREAD_CANCEL_DISABLE:
89 curthread->cancel_enable = 0;
90 THR_UNLOCK(curthread);
92 case PTHREAD_CANCEL_ENABLE:
94 curthread->cancel_enable = 1;
95 THR_UNLOCK(curthread);
102 *oldstate = oldval ? PTHREAD_CANCEL_ENABLE :
103 PTHREAD_CANCEL_DISABLE;
109 _pthread_setcanceltype(int type, int *oldtype)
111 struct pthread *curthread = _get_curthread();
114 oldval = curthread->cancel_async;
116 case PTHREAD_CANCEL_ASYNCHRONOUS:
117 curthread->cancel_async = 1;
118 testcancel(curthread);
120 case PTHREAD_CANCEL_DEFERRED:
121 curthread->cancel_async = 0;
128 *oldtype = oldval ? PTHREAD_CANCEL_ASYNCHRONOUS :
129 PTHREAD_CANCEL_DEFERRED;
135 _pthread_testcancel(void)
137 struct pthread *curthread = _get_curthread();
139 _thr_cancel_enter(curthread);
140 _thr_cancel_leave(curthread);
144 _thr_cancel_enter(struct pthread *curthread)
146 if (curthread->cancel_enable) {
147 curthread->cancel_point++;
148 testcancel(curthread);
153 _thr_cancel_leave(struct pthread *curthread)
155 if (curthread->cancel_enable)
156 curthread->cancel_point--;
160 _thr_cancel_enter_defer(struct pthread *curthread)
162 if (curthread->cancel_enable) {
163 curthread->cancel_point++;
164 testcancel(curthread);
165 curthread->cancel_defer++;
170 _thr_cancel_leave_defer(struct pthread *curthread, int check)
172 if (curthread->cancel_enable) {
174 curthread->cancel_point--;
175 curthread->cancel_defer--;
177 curthread->cancel_defer--;
178 testcancel(curthread);
179 curthread->cancel_point--;