Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / native_client_sdk / src / libraries / third_party / pthreads-win32 / pthread_cancel.c
blobae60b72936d3ea16046e4c16593157b13bcd2fc7
1 /*
2 * pthread_cancel.c
4 * Description:
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
37 #include "pthread.h"
38 #include "implement.h"
39 #include "context.h"
41 static void
42 ptw32_cancel_self (void)
44 ptw32_throw (PTW32_EPS_CANCEL);
46 /* Never reached */
49 static void CALLBACK
50 ptw32_cancel_callback (ULONG_PTR unused)
52 ptw32_throw (PTW32_EPS_CANCEL);
54 /* Never reached */
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.
62 DWORD
63 ptw32_RegisterCancelation (PAPCFUNC unused1, HANDLE threadH, DWORD unused2)
65 CONTEXT context;
67 context.ContextFlags = CONTEXT_CONTROL;
68 GetThreadContext (threadH, &context);
69 PTW32_PROGCTR (context) = (DWORD_PTR) ptw32_cancel_self;
70 SetThreadContext (threadH, &context);
71 return 0;
74 int
75 pthread_cancel (pthread_t thread)
77 * ------------------------------------------------------
78 * DOCPUBLIC
79 * This function requests cancellation of 'thread'.
81 * PARAMETERS
82 * thread
83 * reference to an instance of pthread_t
86 * DESCRIPTION
87 * This function requests cancellation of 'thread'.
88 * NOTE: cancellation is asynchronous; use pthread_join to
89 * wait for termination of 'thread' if necessary.
91 * RESULTS
92 * 0 successfully requested cancellation,
93 * ESRCH no thread found corresponding to 'thread',
94 * ENOMEM implicit self thread create failed.
95 * ------------------------------------------------------
98 int result;
99 int cancel_self;
100 pthread_t self;
101 ptw32_thread_t * tp;
102 ptw32_mcs_local_node_t stateLock;
104 result = pthread_kill (thread, 0);
106 if (0 != result)
108 return result;
111 if ((self = pthread_self ()).p == NULL)
113 return ENOMEM;
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
120 * safe function).
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)
135 if (cancel_self)
137 tp->state = PThreadStateCanceling;
138 tp->cancelState = PTHREAD_CANCEL_DISABLE;
140 ptw32_mcs_lock_release (&stateLock);
141 ptw32_throw (PTW32_EPS_CANCEL);
143 /* Never reached */
145 else
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);
167 else
170 * Set for deferred cancellation.
172 if (tp->state < PThreadStateCancelPending)
174 tp->state = PThreadStateCancelPending;
175 if (!SetEvent (tp->cancelEvent))
177 result = ESRCH;
180 else if (tp->state >= PThreadStateCanceling)
182 result = ESRCH;
185 ptw32_mcs_lock_release (&stateLock);
188 return (result);