2 * David Leonard <d@openbsd.org>, 1999. Public domain.
8 #include "pthread_private.h"
11 pthread_cancel(pthread_t pthread)
15 if ((ret = _find_thread(pthread)) != 0) {
17 } else if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK) {
20 /* Protect the scheduling queues: */
21 _thread_kern_sig_defer();
23 /* Check if we need to kick it back into the run queue: */
24 if ((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0)
25 switch (pthread->state) {
27 /* No need to resume: */
28 pthread->cancelflags |= PTHREAD_CANCELLING;
36 /* Remove these threads from the work queue: */
37 if ((pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
39 PTHREAD_WORKQ_REMOVE(pthread);
47 /* Interrupt and resume: */
48 pthread->interrupted = 1;
49 pthread->cancelflags |= PTHREAD_CANCELLING;
50 PTHREAD_NEW_STATE(pthread,PS_RUNNING);
60 * Threads in these states may be in queues.
61 * In order to preserve queue integrity, the
62 * cancelled thread must remove itself from the
63 * queue. Mark the thread as interrupted and
64 * needing cancellation, and set the state to
65 * running. When the thread resumes, it will
66 * exit after removing itself from the queue.
68 pthread->interrupted = 1;
69 pthread->cancelflags |= PTHREAD_CANCEL_NEEDED;
70 PTHREAD_NEW_STATE(pthread,PS_RUNNING);
76 /* Ignore - only here to silence -Wall: */
79 /* Unprotect the scheduling queues: */
80 _thread_kern_sig_undefer();
88 pthread_setcancelstate(int state, int *oldstate)
93 ostate = _thread_run->cancelflags & PTHREAD_CANCEL_DISABLE;
96 case PTHREAD_CANCEL_ENABLE:
99 _thread_run->cancelflags &= PTHREAD_CANCEL_ENABLE;
100 if ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)
101 pthread_testcancel();
104 case PTHREAD_CANCEL_DISABLE:
105 if (oldstate != NULL)
107 _thread_run->cancelflags |= PTHREAD_CANCEL_DISABLE;
118 pthread_setcanceltype(int type, int *oldtype)
123 otype = _thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS;
125 case PTHREAD_CANCEL_ASYNCHRONOUS:
128 _thread_run->cancelflags |= PTHREAD_CANCEL_ASYNCHRONOUS;
129 pthread_testcancel();
132 case PTHREAD_CANCEL_DEFERRED:
135 _thread_run->cancelflags &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
146 pthread_testcancel(void)
149 if (((_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) &&
150 ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0)) {
152 * It is possible for this thread to be swapped out
153 * while performing cancellation; do not allow it
154 * to be cancelled again.
156 _thread_run->cancelflags &= ~PTHREAD_CANCELLING;
157 _thread_exit_cleanup();
158 pthread_exit(PTHREAD_CANCELED);
164 _thread_enter_cancellation_point(void)
167 /* Look for a cancellation before we block: */
168 pthread_testcancel();
169 _thread_run->cancelflags |= PTHREAD_AT_CANCEL_POINT;
173 _thread_leave_cancellation_point(void)
176 _thread_run->cancelflags &= ~PTHREAD_AT_CANCEL_POINT;
177 /* Look for a cancellation after we unblock: */
178 pthread_testcancel();