pthread_t ptw32_new (void) { pthread_t t; pthread_t nil = {NULL, 0}; ptw32_thread_t * tp; /* * If there's a reusable pthread_t then use it. */ t = ptw32_threadReusePop (); if (NULL != t.p) { tp = (ptw32_thread_t *) t.p; } else { /* No reuse threads available */ tp = (ptw32_thread_t *) calloc (1, sizeof(ptw32_thread_t)); if (tp == NULL) { return nil; } /* ptHandle.p needs to point to it's parent ptw32_thread_t. */ t.p = tp->ptHandle.p = tp; t.x = tp->ptHandle.x = 0; } /* Set default state. */ tp->seqNumber = ++ptw32_threadSeqNumber; tp->sched_priority = THREAD_PRIORITY_NORMAL; tp->detachState = PTHREAD_CREATE_JOINABLE; tp->cancelState = PTHREAD_CANCEL_ENABLE; tp->cancelType = PTHREAD_CANCEL_DEFERRED; tp->stateLock = 0; tp->threadLock = 0; tp->robustMxListLock = 0; tp->robustMxList = NULL; tp->name = NULL; #if defined(HAVE_CPU_AFFINITY) CPU_ZERO((cpu_set_t*)&tp->cpuset); #endif tp->cancelEvent = CreateEvent (0, (int) PTW32_TRUE, /* manualReset */ (int) PTW32_FALSE, /* setSignaled */ NULL); if (tp->cancelEvent == NULL) { ptw32_threadReusePush (tp->ptHandle); return nil; } return t; }
pthread_t pthread_self (void) { pthread_t self; pthread_t nil = {NULL, 0}; ptw32_thread_t * sp; #if defined(_UWIN) if (!ptw32_selfThreadKey) return nil; #endif sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); if (sp != NULL) { self = sp->ptHandle; } else { self = ptw32_new (); sp = (ptw32_thread_t *) self.p; if (sp != NULL) { sp->implicit = 1; sp->detachState = PTHREAD_CREATE_DETACHED; sp->thread = GetCurrentThreadId (); #if defined(NEED_DUPLICATEHANDLE) sp->threadH = GetCurrentThread (); #else if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), GetCurrentProcess (), &sp->threadH, 0, FALSE, DUPLICATE_SAME_ACCESS)) { ptw32_threadReusePush (self); return nil; } #endif sp->sched_priority = GetThreadPriority (sp->threadH); pthread_setspecific (ptw32_selfThreadKey, (void *) sp); } } return (self); }
pthread_t ptw32_new (void) { pthread_t t; pthread_t nil = {NULL, 0}; ptw32_thread_t * tp; /* * If there's a reusable pthread_t then use it. */ t = ptw32_threadReusePop (); if (NULL != t.p) { tp = (ptw32_thread_t *) t.p; } else { /* No reuse threads available */ tp = (ptw32_thread_t *) calloc (1, sizeof(ptw32_thread_t)); if (tp == NULL) { return nil; } /* ptHandle.p needs to point to it's parent ptw32_thread_t. */ t.p = tp->ptHandle.p = tp; t.x = tp->ptHandle.x = 0; } /* Set default state. */ tp->sched_priority = THREAD_PRIORITY_NORMAL; tp->detachState = PTHREAD_CREATE_JOINABLE; tp->cancelState = PTHREAD_CANCEL_ENABLE; tp->cancelType = PTHREAD_CANCEL_DEFERRED; tp->cancelLock = PTHREAD_MUTEX_INITIALIZER; tp->threadLock = PTHREAD_MUTEX_INITIALIZER; tp->cancelEvent = CreateEvent (0, (int) PTW32_TRUE, /* manualReset */ (int) PTW32_FALSE, /* setSignaled */ NULL); if (tp->cancelEvent == NULL) { ptw32_threadReusePush (tp->ptHandle); return nil; } return t; }
void ptw32_threadDestroy (pthread_t thread) { struct pthread_t_ threadCopy; if (thread != NULL) { (void) pthread_mutex_lock(&thread->cancelLock); thread->state = PThreadStateLast; (void) pthread_mutex_unlock(&thread->cancelLock); ptw32_callUserDestroyRoutines (thread); /* * Copy thread state so that the thread can be atomically NULLed. */ memcpy(&threadCopy, thread, sizeof(threadCopy)); /* * Thread ID structs are never freed. They're NULLed and reused. * This also sets the thread to PThreadStateInitial (invalid). */ ptw32_threadReusePush(thread); /* Now work on the copy. */ if (threadCopy.cancelEvent != NULL) { CloseHandle (threadCopy.cancelEvent); } (void) pthread_mutex_destroy(&threadCopy.cancelLock); #if ! defined (__MINGW32__) || defined (__MSVCRT__) /* * See documentation for endthread vs endthreadex. * Don't close the Win32 handle of implicit POSIX threads * because the process may want to call GetExitCodeThread(). */ if( threadCopy.threadH != 0 && ! threadCopy.implicit ) { CloseHandle( threadCopy.threadH ); } #endif } } /* ptw32_threadDestroy */
void ptw32_threadDestroy (pthread_t thread) { ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; ptw32_thread_t threadCopy; if (tp != NULL) { /* * Copy thread state so that the thread can be atomically NULLed. */ memcpy (&threadCopy, tp, sizeof (threadCopy)); /* * Thread ID structs are never freed. They're NULLed and reused. * This also sets the thread to PThreadStateInitial (invalid). */ ptw32_threadReusePush (thread); /* Now work on the copy. */ if (threadCopy.cancelEvent != NULL) { CloseHandle (threadCopy.cancelEvent); } (void) pthread_mutex_destroy(&threadCopy.cancelLock); (void) pthread_mutex_destroy(&threadCopy.threadLock); #if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) /* * See documentation for endthread vs endthreadex. */ if (threadCopy.threadH != 0) { CloseHandle (threadCopy.threadH); } #endif } } /* ptw32_threadDestroy */
pthread_t ptw32_new (void) { pthread_t t; /* * If there's a reusable pthread_t then use it. */ t = ptw32_threadReusePop (); if (NULL == t) { t = (pthread_t) calloc (1, sizeof (*t)); } if (t != NULL) { t->sched_priority = THREAD_PRIORITY_NORMAL; t->detachState = PTHREAD_CREATE_JOINABLE; t->cancelState = PTHREAD_CANCEL_ENABLE; t->cancelType = PTHREAD_CANCEL_DEFERRED; t->cancelLock = PTHREAD_MUTEX_INITIALIZER; t->threadLock = PTHREAD_MUTEX_INITIALIZER; t->cancelEvent = CreateEvent (0, (int) PTW32_TRUE, /* manualReset */ (int) PTW32_FALSE, /* setSignaled */ NULL); if (t->cancelEvent == NULL) { /* * Thread ID structs are never freed. */ ptw32_threadReusePush (t); t = NULL; } } return t; }
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; pthread_t nil = {NULL, 0}; ptw32_thread_t * sp; if (!ptw32_processInitialize()) return nil; #if defined(_UWIN) if (!ptw32_selfThreadKey) return nil; #endif sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); if (sp != NULL) { self = sp->ptHandle; } else { /* * Need to create an implicit 'self' for the currently * executing thread. */ self = ptw32_new (); sp = (ptw32_thread_t *) self.p; if (sp != 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. */ sp->implicit = 1; sp->detachState = PTHREAD_CREATE_DETACHED; sp->thread = GetCurrentThreadId (); #if defined(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. */ sp->threadH = GetCurrentThread (); #else if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), GetCurrentProcess (), &sp->threadH, 0, FALSE, DUPLICATE_SAME_ACCESS)) { /* * Should not do this, but we have no alternative if * we can't get a Win32 thread handle. * Thread structs are never freed. */ sp->threadH = 0; ptw32_threadReusePush (self); /* * As this is a win32 thread calling us and we have failed, * return a value that makes sense to win32. */ return nil; } #endif /* * No need to explicitly serialise access to sched_priority * because the new handle is not yet public. */ sp->sched_priority = GetThreadPriority (sp->threadH); pthread_setspecific (ptw32_selfThreadKey, (void *) sp); } } return (self); } /* pthread_self */
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; pthread_t nil = {NULL, 0}; ptw32_thread_t * sp; #if defined(_UWIN) if (!ptw32_selfThreadKey) return nil; #endif sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); if (sp != NULL) { self = sp->ptHandle; } else { int fail = PTW32_FALSE; /* * Need to create an implicit 'self' for the currently * executing thread. */ self = ptw32_new (); sp = (ptw32_thread_t *) self.p; if (sp != 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. */ sp->implicit = 1; sp->detachState = PTHREAD_CREATE_DETACHED; sp->thread = GetCurrentThreadId (); #if defined(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. */ sp->threadH = GetCurrentThread (); #else if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), GetCurrentProcess (), &sp->threadH, 0, FALSE, DUPLICATE_SAME_ACCESS)) { fail = PTW32_TRUE; } #endif if (!fail) { #if defined(HAVE_CPU_AFFINITY) /* * Get this threads CPU affinity by temporarily setting the threads * affinity to that of the process to get the old thread affinity, * then reset to the old affinity. */ DWORD_PTR vThreadMask, vProcessMask, vSystemMask; if (GetProcessAffinityMask(GetCurrentProcess(), &vProcessMask, &vSystemMask)) { vThreadMask = SetThreadAffinityMask(sp->threadH, vProcessMask); if (vThreadMask) { if (SetThreadAffinityMask(sp->threadH, vThreadMask)) { sp->cpuset = (size_t) vThreadMask; } else fail = PTW32_TRUE; } else fail = PTW32_TRUE; } else fail = PTW32_TRUE; #endif /* * No need to explicitly serialise access to sched_priority * because the new handle is not yet public. */ sp->sched_priority = GetThreadPriority (sp->threadH); pthread_setspecific (ptw32_selfThreadKey, (void *) sp); } } if (fail) { /* * Thread structs are never freed but are reused so if this * continues to fail at least we don't leak memory. */ ptw32_threadReusePush (self); /* * As this is a win32 thread calling us and we have failed, * return a value that makes sense to win32. */ return nil; } } return (self); }
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)) { /* Thread structs are never freed. */ ptw32_threadReusePush (self); return (NULL); } #endif /* * No need to explicitly serialise access to sched_priority * because the new handle is not yet public. */ self->sched_priority = GetThreadPriority (self->threadH); } pthread_setspecific (ptw32_selfThreadKey, self); } return (self); } /* pthread_self */