15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pthread_cancel.c 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Description: 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * POSIX thread functions related to thread cancellation. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -------------------------------------------------------------------------- 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Pthreads-win32 - POSIX Threads Library for Win32 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright(C) 1998 John E. Bossom 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright(C) 1999,2005 Pthreads-win32 contributors 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Contact Email: rpj@callisto.canberra.edu.au 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The current list of contributors is contained 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the file CONTRIBUTORS included with the source 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * code distribution. The list can also be seen at the 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * following World Wide Web location: 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://sources.redhat.com/pthreads-win32/contributors.html 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This library is free software; you can redistribute it and/or 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modify it under the terms of the GNU Lesser General Public 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License as published by the Free Software Foundation; either 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * version 2 of the License, or (at your option) any later version. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This library is distributed in the hope that it will be useful, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Lesser General Public License for more details. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You should have received a copy of the GNU Lesser General Public 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License along with this library in the file COPYING.LIB; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if not, write to the Free Software Foundation, Inc., 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pthread.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "implement.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "context.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ptw32_cancel_self (void) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_throw (PTW32_EPS_CANCEL); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Never reached */ 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CALLBACK 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ptw32_cancel_callback (ULONG_PTR unused) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_throw (PTW32_EPS_CANCEL); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Never reached */ 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ptw32_RegisterCancelation() - 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Must have args of same type as QueueUserAPCEx because this function 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is a substitute for QueueUserAPCEx if it's not available. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ptw32_RegisterCancelation (PAPCFUNC unused1, HANDLE threadH, DWORD unused2) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTEXT context; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context.ContextFlags = CONTEXT_CONTROL; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetThreadContext (threadH, &context); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PTW32_PROGCTR (context) = (DWORD_PTR) ptw32_cancel_self; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetThreadContext (threadH, &context); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pthread_cancel (pthread_t thread) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ------------------------------------------------------ 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DOCPUBLIC 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function requests cancellation of 'thread'. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PARAMETERS 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * thread 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reference to an instance of pthread_t 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DESCRIPTION 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function requests cancellation of 'thread'. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOTE: cancellation is asynchronous; use pthread_join to 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * wait for termination of 'thread' if necessary. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RESULTS 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 0 successfully requested cancellation, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ESRCH no thread found corresponding to 'thread', 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ENOMEM implicit self thread create failed. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ------------------------------------------------------ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cancel_self; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_t self; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_thread_t * tp; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_mcs_local_node_t stateLock; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = pthread_kill (thread, 0); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 != result) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((self = pthread_self ()).p == NULL) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ENOMEM; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For self cancellation we need to ensure that a thread can't 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * deadlock itself trying to cancel itself asynchronously 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (pthread_cancel is required to be an async-cancel 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * safe function). 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel_self = pthread_equal (thread, self); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tp = (ptw32_thread_t *) thread.p; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Lock for async-cancel safety. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && tp->cancelState == PTHREAD_CANCEL_ENABLE 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && tp->state < PThreadStateCanceling) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cancel_self) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tp->state = PThreadStateCanceling; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tp->cancelState = PTHREAD_CANCEL_DISABLE; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_mcs_lock_release (&stateLock); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_throw (PTW32_EPS_CANCEL); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Never reached */ 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE threadH = tp->threadH; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SuspendThread (threadH); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (WaitForSingleObject (threadH, 0) == WAIT_TIMEOUT) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tp->state = PThreadStateCanceling; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tp->cancelState = PTHREAD_CANCEL_DISABLE; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If alertdrv and QueueUserAPCEx is available then the following 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will result in a call to QueueUserAPCEx with the args given, otherwise 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this will result in a call to ptw32_RegisterCancelation and only 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the threadH arg will be used. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_register_cancelation ((PAPCFUNC)ptw32_cancel_callback, threadH, 0); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_mcs_lock_release (&stateLock); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResumeThread (threadH); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Set for deferred cancellation. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tp->state < PThreadStateCancelPending) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tp->state = PThreadStateCancelPending; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SetEvent (tp->cancelEvent)) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = ESRCH; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (tp->state >= PThreadStateCanceling) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = ESRCH; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptw32_mcs_lock_release (&stateLock); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (result); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 190