diff options
author | rpj <rpj> | 2002-02-11 01:53:22 +0000 |
---|---|---|
committer | rpj <rpj> | 2002-02-11 01:53:22 +0000 |
commit | e6f1797e9e9925ae7f9dda54806ef8f52ae3ed07 (patch) | |
tree | c513bf622584d48383ce9d167159c81baa71b3f9 /w32_CancelableWait.c | |
parent | 1cf6fdda9842e5b728cdce93683292f4380a4572 (diff) |
Splitting files. See ChangeLog file for details.
Diffstat (limited to 'w32_CancelableWait.c')
-rw-r--r-- | w32_CancelableWait.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/w32_CancelableWait.c b/w32_CancelableWait.c new file mode 100644 index 0000000..ba1c92a --- /dev/null +++ b/w32_CancelableWait.c @@ -0,0 +1,168 @@ +/* + * w32_CancelableWait.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +static INLINE int +ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout) + /* + * ------------------------------------------------------------------- + * This provides an extra hook into the pthread_cancel + * mechanism that will allow you to wait on a Windows handle and make it a + * cancellation point. This function blocks until the given WIN32 handle is + * signaled or pthread_cancel has been called. It is implemented using + * WaitForMultipleObjects on 'waitHandle' and a manually reset WIN32 + * event used to implement pthread_cancel. + * + * Given this hook it would be possible to implement more of the cancellation + * points. + * ------------------------------------------------------------------- + */ +{ + int result; + pthread_t self; + HANDLE handles[2]; + DWORD nHandles = 1; + DWORD status; + + handles[0] = waitHandle; + + if ((self = pthread_self()) != NULL) + { + /* + * Get cancelEvent handle + */ + if (self->cancelState == PTHREAD_CANCEL_ENABLE) + { + + if ((handles[1] = self->cancelEvent) != NULL) + { + nHandles++; + } + } + } + else + { + handles[1] = NULL; + } + + status = WaitForMultipleObjects ( + nHandles, + handles, + FALSE, + timeout); + + + if (status == WAIT_FAILED) + { + result = EINVAL; + } + else if (status == WAIT_TIMEOUT) + { + result = ETIMEDOUT; + } + else if (status == WAIT_ABANDONED_0) + { + result = EINVAL; + } + else + { + /* + * Either got the handle or the cancel event + * was signaled + */ + switch (status - WAIT_OBJECT_0) + { + + case 0: + /* + * Got the handle + */ + result = 0; + break; + + case 1: + /* + * Got cancel request + */ + ResetEvent (handles[1]); + + if (self != NULL && !self->implicit) + { + /* + * Thread started with pthread_create. + * Make sure we haven't been async-canceled in the meantime. + */ + (void) pthread_mutex_lock(&self->cancelLock); + if (self->state < PThreadStateCanceling) + { + self->state = PThreadStateCanceling; + self->cancelState = PTHREAD_CANCEL_DISABLE; + (void) pthread_mutex_unlock(&self->cancelLock); + ptw32_throw(PTW32_EPS_CANCEL); + + /* Never reached */ + } + (void) pthread_mutex_unlock(&self->cancelLock); + } + + /* Should never get to here. */ + result = EINVAL; + break; + + default: + result = EINVAL; + break; + } + } + + return (result); + +} /* CancelableWait */ + +int +pthreadCancelableWait (HANDLE waitHandle) +{ + return (ptw32_cancelable_wait(waitHandle, INFINITE)); +} + +int +pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout) +{ + return (ptw32_cancelable_wait(waitHandle, timeout)); +} |