5 * POSIX thread functions related to thread cancellation.
7 * --------------------------------------------------------------------------
9 * Pthreads-win32 - POSIX Threads Library for Win32
10 * Copyright(C) 1998 John E. Bossom
11 * Copyright(C) 1999,2005 Pthreads-win32 contributors
13 * Contact Email: rpj@callisto.canberra.edu.au
15 * The current list of contributors is contained
16 * in the file CONTRIBUTORS included with the source
17 * code distribution. The list can also be seen at the
18 * following World Wide Web location:
19 * http://sources.redhat.com/pthreads-win32/contributors.html
21 * This library is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU Lesser General Public
23 * License as published by the Free Software Foundation; either
24 * version 2 of the License, or (at your option) any later version.
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library in the file COPYING.LIB;
33 * if not, write to the Free Software Foundation, Inc.,
34 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
38 #include "implement.h"
42 ptw32_cancel_self (void)
44 ptw32_throw (PTW32_EPS_CANCEL
);
50 ptw32_cancel_callback (ULONG_PTR unused
)
52 ptw32_throw (PTW32_EPS_CANCEL
);
58 * ptw32_RegisterCancelation() -
59 * Must have args of same type as QueueUserAPCEx because this function
60 * is a substitute for QueueUserAPCEx if it's not available.
63 ptw32_RegisterCancelation (PAPCFUNC unused1
, HANDLE threadH
, DWORD unused2
)
67 context
.ContextFlags
= CONTEXT_CONTROL
;
68 GetThreadContext (threadH
, &context
);
69 PTW32_PROGCTR (context
) = (DWORD_PTR
) ptw32_cancel_self
;
70 SetThreadContext (threadH
, &context
);
75 pthread_cancel (pthread_t thread
)
77 * ------------------------------------------------------
79 * This function requests cancellation of 'thread'.
83 * reference to an instance of pthread_t
87 * This function requests cancellation of 'thread'.
88 * NOTE: cancellation is asynchronous; use pthread_join to
89 * wait for termination of 'thread' if necessary.
92 * 0 successfully requested cancellation,
93 * ESRCH no thread found corresponding to 'thread',
94 * ENOMEM implicit self thread create failed.
95 * ------------------------------------------------------
102 ptw32_mcs_local_node_t stateLock
;
104 result
= pthread_kill (thread
, 0);
111 if ((self
= pthread_self ()).p
== NULL
)
117 * For self cancellation we need to ensure that a thread can't
118 * deadlock itself trying to cancel itself asynchronously
119 * (pthread_cancel is required to be an async-cancel
122 cancel_self
= pthread_equal (thread
, self
);
124 tp
= (ptw32_thread_t
*) thread
.p
;
127 * Lock for async-cancel safety.
129 ptw32_mcs_lock_acquire (&tp
->stateLock
, &stateLock
);
131 if (tp
->cancelType
== PTHREAD_CANCEL_ASYNCHRONOUS
132 && tp
->cancelState
== PTHREAD_CANCEL_ENABLE
133 && tp
->state
< PThreadStateCanceling
)
137 tp
->state
= PThreadStateCanceling
;
138 tp
->cancelState
= PTHREAD_CANCEL_DISABLE
;
140 ptw32_mcs_lock_release (&stateLock
);
141 ptw32_throw (PTW32_EPS_CANCEL
);
147 HANDLE threadH
= tp
->threadH
;
149 SuspendThread (threadH
);
151 if (WaitForSingleObject (threadH
, 0) == WAIT_TIMEOUT
)
153 tp
->state
= PThreadStateCanceling
;
154 tp
->cancelState
= PTHREAD_CANCEL_DISABLE
;
156 * If alertdrv and QueueUserAPCEx is available then the following
157 * will result in a call to QueueUserAPCEx with the args given, otherwise
158 * this will result in a call to ptw32_RegisterCancelation and only
159 * the threadH arg will be used.
161 ptw32_register_cancelation ((PAPCFUNC
)ptw32_cancel_callback
, threadH
, 0);
162 ptw32_mcs_lock_release (&stateLock
);
163 ResumeThread (threadH
);
170 * Set for deferred cancellation.
172 if (tp
->state
< PThreadStateCancelPending
)
174 tp
->state
= PThreadStateCancelPending
;
175 if (!SetEvent (tp
->cancelEvent
))
180 else if (tp
->state
>= PThreadStateCanceling
)
185 ptw32_mcs_lock_release (&stateLock
);