diff options
author | rpj <rpj> | 1999-01-03 18:47:50 +0000 |
---|---|---|
committer | rpj <rpj> | 1999-01-03 18:47:50 +0000 |
commit | 36f0ed4155fdab7b12c5c5ddf4252170fac0a77e (patch) | |
tree | 2d8ed62df0b72d42a74b383d389ee7c28a0324da /misc.c | |
parent | 4650bcf1f1efd88a0c8f502c28945bfabd7ef6db (diff) |
Merge John Bossom's code into the main trunk. See ChangeLog for details.snapshot-1999-01-04-1305
This will be tagged as snapshot-1999-01-04-1305
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 211 |
1 files changed, 198 insertions, 13 deletions
@@ -8,6 +8,7 @@ #include <errno.h> #include "pthread.h" +#include "implement.h" int pthread_once(pthread_once_t *once_control, @@ -39,25 +40,209 @@ pthread_once(pthread_once_t *once_control, return 0; } +/* + * Code contributed by John E. Bossom <JEB>. + */ + pthread_t -pthread_self(void) +pthread_self (void) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function returns a reference to the current running + * thread. + * + * PARAMETERS + * N/A + * + * + * DESCRIPTION + * This function returns a reference to the current running + * thread. + * + * RESULTS + * pthread_t reference to the current thread + * + * ------------------------------------------------------ + */ { - pthread_t ret; - /* This TLS index is allocated on DLL load by dll.c */ - extern DWORD _pthread_threadID_TlsIndex; - - ret = (pthread_t) TlsGetValue(_pthread_threadID_TlsIndex); + pthread_t self = NULL; + /* + * need to ensure there always is a self + */ - if (ret == 0) + if ((self = pthread_getspecific (_pthread_selfThreadKey)) == NULL) { - /* FIXME: Oh no! This can't happen. */ + /* + * Need to create an implicit 'self' for the currently + * executing thread. + */ + self = (pthread_t) calloc (1, sizeof (*self)); + if (self != NULL) + { + + self->implicit = 1; + self->detachState = PTHREAD_CREATE_DETACHED; + + self->thread = GetCurrentThreadId (); + self->threadH = GetCurrentThread (); + } + + pthread_setspecific (_pthread_selfThreadKey, self); } - return ret; -} + return (self); + +} /* pthread_self */ int -pthread_equal(pthread_t t1, pthread_t t2) +pthread_equal (pthread_t t1, pthread_t t2) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function returns zero if t1 and t2 are equal, else + * returns nonzero + * + * PARAMETERS + * t1, + * t2 + * references to an instances of thread_t + * + * + * DESCRIPTION + * This function returns zero if t1 and t2 are equal, else + * returns nonzero. + * + * RESULTS + * 0 if t1 and t2 refer to the same thread, + * non-zero t1 and t2 do not refer to the same thread + * + * ------------------------------------------------------ + */ { - return (t1 == t2); -} + int result; + + result = !((t1 == t2) || (t1->thread == t2->thread)); + + return (result); + +} /* pthread_equal */ + + +int +pthreadCancelableWait (HANDLE waitHandle) + /* + * ------------------------------------------------------------------- + * 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_getspecific (_pthread_selfThreadKey)) != 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, + INFINITE); + + + if (status == WAIT_FAILED) + { + result = EINVAL; + + } + else if (status == WAIT_ABANDONED_0) + { + result = EINVAL; + + } + else + { + /* + * Either got the mutex or the cancel event + * was signaled + */ + switch (status - WAIT_OBJECT_0) + { + + case 0: + /* + * Got the mutex + */ + result = 0; + break; + + case 1: + /* + * Got cancel request + */ + ResetEvent (handles[1]); + + if (self != NULL && !self->implicit) + { + /* + * Thread started with pthread_create + */ + DWORD exceptionInformation[3]; + + exceptionInformation[0] = (DWORD) (0); + exceptionInformation[1] = (DWORD) (0); + + RaiseException ( + EXCEPTION_PTHREAD_SERVICES, + 0, + 3, + exceptionInformation); + } + + + ((void *) -1); + break; + + default: + result = EINVAL; + break; + } + } + + return (result); + +} /* pthreadCancelableWait */ + + +/* </JEB> */ + |