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 /misc.c | |
parent | 1cf6fdda9842e5b728cdce93683292f4380a4572 (diff) |
Splitting files. See ChangeLog file for details.
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 420 |
1 files changed, 8 insertions, 412 deletions
@@ -38,416 +38,12 @@ #include "implement.h" -int -pthread_once ( - pthread_once_t * once_control, - void (*init_routine) (void) -) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * If any thread in a process with a once_control parameter - * makes a call to pthread_once(), the first call will summon - * the init_routine(), but subsequent calls will not. The - * once_control parameter determines whether the associated - * initialization routine has been called. The init_routine() - * is complete upon return of pthread_once(). - * This function guarantees that one and only one thread - * executes the initialization routine, init_routine when - * access is controlled by the pthread_once_t control - * key. - * - * PARAMETERS - * once_control - * pointer to an instance of pthread_once_t - * - * init_routine - * pointer to an initialization routine - * - * - * DESCRIPTION - * See above. - * - * RESULTS - * 0 success, - * EINVAL once_control or init_routine is NULL - * - * ------------------------------------------------------ - */ -{ - int result; +#include "pthread_once.c" +#include "pthread_self.c" +#include "pthread_equal.c" +#include "pthread_setconcurrency.c" +#include "pthread_getconcurrency.c" +#include "w32_CancelableWait.c" +#include "ptw32_new.c" +#include "ptw32_calloc.c" - if (once_control == NULL || init_routine == NULL) - { - - result = EINVAL; - goto FAIL0; - - } - else - { - result = 0; - } - - if (!once_control->done) - { - if (InterlockedIncrement (&(once_control->started)) == 0) - { - /* - * First thread to increment the started variable - */ - (*init_routine) (); - once_control->done = TRUE; - - } - else - { - /* - * Block until other thread finishes executing the onceRoutine - */ - while (!(once_control->done)) - { - /* - * The following gives up CPU cycles without pausing - * unnecessarily - */ - Sleep (0); - } - } - } - - /* - * Fall through Intentionally - */ - - /* - * ------------ - * Failure Code - * ------------ - */ -FAIL0: - return (result); - -} /* pthread_once */ - - -pthread_t -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 self; - -#ifdef _UWIN - if(!ptw32_selfThreadKey) - return(NULL); -#endif - - self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); - - if (self == NULL) - { - /* - * Need to create an implicit 'self' for the currently - * executing thread. - */ - self = ptw32_new(); - - if (self != NULL) - { - /* - * This is a non-POSIX thread which has chosen to call - * a POSIX threads function for some reason. We assume that - * it isn't joinable, but we do assume that it's - * (deferred) cancelable. - */ - self->implicit = 1; - self->detachState = PTHREAD_CREATE_DETACHED; - self->thread = GetCurrentThreadId (); - -#ifdef NEED_DUPLICATEHANDLE - /* - * DuplicateHandle does not exist on WinCE. - * - * NOTE: - * GetCurrentThread only returns a pseudo-handle - * which is only valid in the current thread context. - * Therefore, you should not pass the handle to - * other threads for whatever purpose. - */ - self->threadH = GetCurrentThread(); -#else - if( !DuplicateHandle( - GetCurrentProcess(), - GetCurrentThread(), - GetCurrentProcess(), - &self->threadH, - 0, - FALSE, - DUPLICATE_SAME_ACCESS ) ) - { - free( self ); - return (NULL); - } -#endif - } - - pthread_setspecific (ptw32_selfThreadKey, self); - } - - return (self); - -} /* pthread_self */ - -int -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 nonzero if t1 and t2 are equal, else - * returns zero. - * - * RESULTS - * non-zero if t1 and t2 refer to the same thread, - * 0 t1 and t2 do not refer to the same thread - * - * ------------------------------------------------------ - */ -{ - int result; - - /* - * We also accept NULL == NULL - treating NULL as a thread - * for this special case, because there is no error that we can return. - */ - result = ( ( t1 == t2 ) && ( t1 == NULL || ( t1->thread == t2->thread ) ) ); - - return (result); - -} /* pthread_equal */ - - -int -pthread_setconcurrency(int level) -{ - if (level < 0) - { - return EINVAL; - } - else - { - ptw32_concurrency = level; - return 0; - } -} - - -int -pthread_getconcurrency(void) -{ - return ptw32_concurrency; -} - - -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)); -} - - -pthread_t -ptw32_new (void) -{ - pthread_t t; - - t = (pthread_t) calloc (1, sizeof (*t)); - - if (t != NULL) - { - t->detachState = PTHREAD_CREATE_JOINABLE; - t->cancelState = PTHREAD_CANCEL_ENABLE; - t->cancelType = PTHREAD_CANCEL_DEFERRED; - t->cancelLock = PTHREAD_MUTEX_INITIALIZER; - t->cancelEvent = CreateEvent ( - 0, - (int) TRUE, /* manualReset */ - (int) FALSE, /* setSignaled */ - NULL); - - if (t->cancelEvent == NULL) - { - free (t); - t = NULL; - } - } - - return t; - -} - - -#ifdef NEED_CALLOC -void * -ptw32_calloc(size_t n, size_t s) { - unsigned int m = n*s; - void *p; - - p = malloc(m); - if (p == NULL) return NULL; - - memset(p, 0, m); - - return p; -} -#endif |