BOOL pthread_win32_process_detach_np () { if (ptw32_processInitialized) { pthread_t self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); /* * Detached threads have their resources automatically * cleaned up upon exit (others must be 'joined'). */ if (self != NULL && self->detachState == PTHREAD_CREATE_DETACHED) { pthread_setspecific (ptw32_selfThreadKey, NULL); ptw32_threadDestroy (self); } /* * The DLL is being unmapped into the process's address space */ ptw32_processTerminate (); if (ptw32_h_kernel32) { (void) FreeLibrary(ptw32_h_kernel32); } } return TRUE; }
int ptw32_processInitialize (void) /* * ------------------------------------------------------ * DOCPRIVATE * This function performs process wide initialization for * the pthread library. * * PARAMETERS * N/A * * DESCRIPTION * This function performs process wide initialization for * the pthread library. * If successful, this routine sets the global variable * ptw32_processInitialized to TRUE. * * RESULTS * TRUE if successful, * FALSE otherwise * * ------------------------------------------------------ */ { if (ptw32_processInitialized) { /* * ignore if already initialized. this is useful for * programs that uses a non-dll pthread * library. such programs must call ptw32_processInitialize() explicitely, * since this initialization routine is automatically called only when * the dll is loaded. */ return TRUE; } ptw32_processInitialized = TRUE; /* * Initialize Keys */ if ((pthread_key_create (&ptw32_selfThreadKey, NULL) != 0) || (pthread_key_create (&ptw32_cleanupKey, NULL) != 0)) { ptw32_processTerminate (); } /* * Set up the global locks. */ InitializeCriticalSection(&ptw32_mutex_test_init_lock); InitializeCriticalSection(&ptw32_cond_list_lock); InitializeCriticalSection(&ptw32_cond_test_init_lock); InitializeCriticalSection(&ptw32_rwlock_test_init_lock); InitializeCriticalSection(&ptw32_spinlock_test_init_lock); return (ptw32_processInitialized); } /* processInitialize */
BOOL pthread_win32_process_detach_np () { if (ptw32_processInitialized) { ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); if (sp != NULL) { /* * Detached threads have their resources automatically * cleaned up upon exit (others must be 'joined'). */ if (sp->detachState == PTHREAD_CREATE_DETACHED) { ptw32_threadDestroy (sp->ptHandle); TlsSetValue (ptw32_selfThreadKey->key, NULL); } } /* * The DLL is being unmapped from the process's address space */ ptw32_processTerminate (); if (ptw32_h_quserex) { /* Close QueueUserAPCEx */ BOOL (*queue_user_apc_ex_fini) (VOID); queue_user_apc_ex_fini = (BOOL (*)(VOID)) #if defined(NEED_UNICODE_CONSTS) GetProcAddress (ptw32_h_quserex, (const TCHAR *) TEXT ("QueueUserAPCEx_Fini")); #else GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Fini"); #endif if (queue_user_apc_ex_fini != NULL) { (void) queue_user_apc_ex_fini (); } (void) FreeLibrary (ptw32_h_quserex); } if (ptw32_h_kernel32) { (void) FreeLibrary (ptw32_h_kernel32); } } return TRUE; }