/* Shutdown TSRM (call once for the entire process) */ TSRM_API void tsrm_shutdown(void) { int i; if (tsrm_tls_table) { for (i=0; i<tsrm_tls_table_size; i++) { tsrm_tls_entry *p = tsrm_tls_table[i], *next_p; while (p) { int j; next_p = p->next; for (j=0; j<p->count; j++) { if (p->storage[j]) { if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { resource_types_table[j].dtor(p->storage[j], &p->storage); } free(p->storage[j]); } } free(p->storage); free(p); p = next_p; } } free(tsrm_tls_table); tsrm_tls_table = NULL; } if (resource_types_table) { free(resource_types_table); resource_types_table=NULL; } tsrm_mutex_free(tsmm_mutex); tsmm_mutex = NULL; TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Shutdown TSRM")); if (tsrm_error_file!=stderr) { fclose(tsrm_error_file); } #if defined(GNUPTH) pth_kill(); #elif defined(PTHREADS) pthread_setspecific(tls_key, 0); pthread_key_delete(tls_key); #elif defined(TSRM_WIN32) TlsFree(tls_key); #endif }
BOOL Init(VOID) { USERCONNECT UserCon; /* Set PEB data */ NtCurrentPeb()->KernelCallbackTable = apfnDispatch; NtCurrentPeb()->PostProcessInitRoutine = NULL; NtUserProcessConnect( NtCurrentProcess(), &UserCon, sizeof(USERCONNECT)); g_ppi = GetWin32ClientInfo()->ppi; // Snapshot PI, used as pointer only! g_ulSharedDelta = UserCon.siClient.ulSharedDelta; gpsi = SharedPtrToUser(UserCon.siClient.psi); gHandleTable = SharedPtrToUser(UserCon.siClient.aheList); gHandleEntries = SharedPtrToUser(gHandleTable->handles); RtlInitializeCriticalSection(&gcsUserApiHook); gfServerProcess = FALSE; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess); //CsrClientConnectToServer(L"\\Windows", 0, NULL, 0, &gfServerProcess); //ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta); /* Allocate an index for user32 thread local data. */ User32TlsIndex = TlsAlloc(); if (User32TlsIndex != TLS_OUT_OF_INDEXES) { if (MessageInit()) { if (MenuInit()) { InitializeCriticalSection(&U32AccelCacheLock); GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); LoadAppInitDlls(); return TRUE; } MessageCleanup(); } TlsFree(User32TlsIndex); } return FALSE; }
extern "C" RCF_BOOST_THREAD_DECL void RBT_on_process_exit(void) { boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex); boost::mutex::scoped_lock lock(*threadmon_mutex); #ifndef __MINGW32__ BOOST_ASSERT(attached_thread_count == 0); #endif //Free the tls slot if one was allocated. if (tls_key != invalid_tls_key) { TlsFree(tls_key); tls_key = invalid_tls_key; } }
/************************************************************************* * SHLWAPI DllMain * * NOTES * calling oleinitialize here breaks some apps. */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad); switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); shlwapi_hInstance = hinstDLL; SHLWAPI_ThreadRef_index = TlsAlloc(); break; case DLL_PROCESS_DETACH: if (fImpLoad) break; if (SHLWAPI_ThreadRef_index != TLS_OUT_OF_INDEXES) TlsFree(SHLWAPI_ThreadRef_index); break; } return TRUE; }
KHMEXP void KHMAPI kmm_exit(void) { kmm_module_i * m; kmm_plugin_i * p; EnterCriticalSection(&cs_kmm); p = kmm_listed_plugins; while(p) { kmm_plugin_i * pn; pn = LNEXT(p); /* plugins that were never resolved should be kicked off the list. Flipping the refcount will do that if no other references exist for the plugin. The plugins that were waiting for unresolved dependencies will automatically get freed when the placeholders and other plugins get freed. */ if(p->state == KMM_PLUGIN_STATE_PLACEHOLDER) { kmm_hold_plugin(kmm_handle_from_plugin(p)); kmm_release_plugin(kmm_handle_from_plugin(p)); } p = pn; } m = kmm_all_modules; while(m) { kmm_unload_module(kmm_handle_from_module(m)); m = LNEXT(m); } LeaveCriticalSection(&cs_kmm); WaitForSingleObject(evt_exit, INFINITE); EnterCriticalSection(&cs_kmm); kmq_post_thread_quit_message(tid_registrar, 0, NULL); hash_del_hashtable(hash_plugins); hash_del_hashtable(hash_modules); LeaveCriticalSection(&cs_kmm); TlsFree(tls_kmm); tls_kmm = 0; }
/* * Creates a thread-local key */ ThrKey THREAD_CreateKey(ThrClean proc) { ASSERT(THREAD_IsInited()); if (THREAD_IsInited()) { DWORD index = TlsAlloc(); ASSERT(index != TLS_OUT_OF_INDEXES); if (index != TLS_OUT_OF_INDEXES) { ThrKey key = MEM_New(struct _ThrKey); if (key) { key->index = index; key->clean = proc; key->ref = 1; return key; } TlsFree(index); } }
HRESULT SyncInit() { if (g_bInited) return S_OK; g_tlsiLdrLoadDllRecursion = TlsAlloc(); if (g_tlsiLdrLoadDllRecursion == TLS_OUT_OF_INDEXES) return E_OUTOFMEMORY; if (!HookBaseInit()) { TlsFree(g_tlsiLdrLoadDllRecursion); return E_FAIL; } return S_OK; }
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { TRACE("(%p, %d, %p)\n", instance, reason, reserved); switch (reason) { case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ case DLL_PROCESS_ATTACH: { SYSTEM_INFO sysinfo; if ((vcomp_context_tls = TlsAlloc()) == TLS_OUT_OF_INDEXES) { ERR("Failed to allocate TLS index\n"); return FALSE; } GetSystemInfo(&sysinfo); vcomp_max_threads = sysinfo.dwNumberOfProcessors; vcomp_num_threads = sysinfo.dwNumberOfProcessors; break; } case DLL_PROCESS_DETACH: { if (reserved) break; if (vcomp_context_tls != TLS_OUT_OF_INDEXES) { vcomp_free_thread_data(); TlsFree(vcomp_context_tls); } break; } case DLL_THREAD_DETACH: { vcomp_free_thread_data(); break; } } return TRUE; }
BOOL APIENTRY DllMain(HMODULE hm, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: InitializeCriticalSection(&threadLock); threadsDone = CreateEvent(NULL, TRUE, FALSE, NULL); break; case DLL_PROCESS_DETACH: terminating = true; if (reserved != NULL) { // process exit(): threads are stopped arbitrarily and // possibly in an inconsistent state. Not even threadLock // can be trusted. All static destructors have been // called at this point and any resources this unit knows // about will be released as part of process tear down by // the OS. Accordingly, do nothing. return TRUE; } else { // FreeLibrary(): threads are still running and we are // encouraged to clean up to avoid leaks. Mostly we just // want any straggler threads to finish and notify // threadsDone as the last thing they do. while (1) { { ScopedCriticalSection l(threadLock); if (runningThreads == 0) break; ResetEvent(threadsDone); } WaitForSingleObject(threadsDone, INFINITE); } if (tlsIndex != TLS_OUT_OF_INDEXES) TlsFree(getTlsIndex()); CloseHandle(threadsDone); DeleteCriticalSection(&threadLock); } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; }
BOOL BtrOnProcessDetach( VOID ) { InterlockedExchange(&BtrUnloading, TRUE); if (FlagOn(BtrFeatures, FeatureLibrary)) { return TRUE; } if (FlagOn(BtrFeatures, FeatureLocal|FeatureRemote)) { if (BtrTlsIndex != TLS_OUT_OF_INDEXES) { TlsFree(BtrTlsIndex); } } return TRUE; }
void vlc_threadvar_delete (vlc_threadvar_t *p_tls) { struct vlc_threadvar *var = *p_tls; EnterCriticalSection(&super_mutex); if (var->prev != NULL) var->prev->next = var->next; if (var->next != NULL) var->next->prev = var->prev; else vlc_threadvar_last = var->prev; LeaveCriticalSection(&super_mutex); TlsFree (var->id); free (var); }
void onProcessDestruction() throw ( ::jace::JNIException ) { #ifdef SUPPORTS_PTHREADS int rc = pthread_key_delete( CLASSLOADER_KEY ); if ( rc != 0 ) { std::string msg = "JNIHelper::setClassLoader()\n" "thread_key_delete() returned " + std::to_string( rc ) + "."; throw JNIException( msg ); } #elif _WIN32 BOOL rc = TlsFree( CLASSLOADER_KEY ); if ( !rc ) { std::string msg = "JNIHelper::setClassLoader()\n" "TlsFree() returned " + std::to_string( GetLastError() ) + "."; throw JNIException( msg ); } #endif }
void vlc_threadvar_delete (vlc_threadvar_t *p_tls) { struct vlc_threadvar *var = *p_tls; vlc_mutex_lock (&super_mutex); if (var->prev != NULL) var->prev->next = var->next; if (var->next != NULL) var->next->prev = var->prev; else vlc_threadvar_last = var->prev; vlc_mutex_unlock (&super_mutex); TlsFree (var->id); free (var); }
/* DLL entry point */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { BOOL ret=TRUE; switch(fdwReason) { case DLL_PROCESS_ATTACH: set_tls_i(TlsAlloc()); ret = (get_tls_i()!=TLS_OUT_OF_INDEXES); break; case DLL_PROCESS_DETACH: if (get_tls_i()!=TLS_OUT_OF_INDEXES) TlsFree(get_tls_i()); break; } return ret; }
/* Entry point called by the DLL loader. */ int WINAPI DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved) { struct tls_space_s *tls; (void)reserved; switch (reason) { case DLL_PROCESS_ATTACH: tls_index = TlsAlloc (); if (tls_index == TLS_OUT_OF_INDEXES) return FALSE; /* falltru. */ case DLL_THREAD_ATTACH: tls = LocalAlloc (LPTR, sizeof *tls); if (!tls) return FALSE; tls->gt_use_utf8 = 0; TlsSetValue (tls_index, tls); if (reason == DLL_PROCESS_ATTACH) { real_init (); } break; case DLL_THREAD_DETACH: tls = TlsGetValue (tls_index); if (tls) LocalFree (tls); break; case DLL_PROCESS_DETACH: tls = TlsGetValue (tls_index); if (tls) LocalFree (tls); TlsFree (tls_index); break; default: break; } return TRUE; }
static VThreadBaseKeyType VThreadBaseGetKey(void) { VThreadBaseKeyType key = Atomic_Read(&vthreadBaseGlobals.key); if (key == VTHREADBASE_INVALID_KEY) { VThreadBaseKeyType newKey; #if defined _WIN32 newKey = TlsAlloc(); ASSERT_NOT_IMPLEMENTED(newKey != VTHREADBASE_INVALID_KEY); #else Bool success = pthread_key_create(&newKey, &VThreadBaseSafeDeleteTLS) == 0; if (success && newKey == 0) { /* * Leak TLS key 0. System libraries have a habit of destroying * it. See bugs 702818 and 773420. */ success = pthread_key_create(&newKey, &VThreadBaseSafeDeleteTLS) == 0; } ASSERT_NOT_IMPLEMENTED(success); #endif if (Atomic_ReadIfEqualWrite(&vthreadBaseGlobals.key, VTHREADBASE_INVALID_KEY, newKey) != VTHREADBASE_INVALID_KEY) { /* Race: someone else init'd */ #if defined _WIN32 TlsFree(newKey); #else pthread_key_delete(newKey); #endif } key = Atomic_Read(&vthreadBaseGlobals.key); ASSERT(key != VTHREADBASE_INVALID_KEY); } return key; }
static void xml_config_close(void) { #if YAZ_HAVE_XML2 if (xml_config_doc) { xmlFreeDoc(xml_config_doc); xml_config_doc = 0; } #endif gfs_server_list = 0; nmem_destroy(gfs_nmem); #ifdef WIN32 if (init_control_tls) TlsFree(current_control_tls); #elif YAZ_POSIX_THREADS if (init_control_tls) pthread_key_delete(current_control_tls); #endif }
BOOL Module::Detach() { ErrorInfo::Fini(); if (m_dwTlsIndex != TLS_OUT_OF_INDEXES) { TlsFree(m_dwTlsIndex); m_dwTlsIndex = TLS_OUT_OF_INDEXES; } if (m_pGIT != NULL) { m_pGIT->Release(); m_pGIT = NULL; } return TRUE; }
/* * This function should be called by the user when the process ends, * to free the local storage index */ ITT_EXTERN_C void JITAPI FinalizeProcess() { if (m_libHandle) { #if ITT_PLATFORM==ITT_PLATFORM_WIN FreeLibrary(m_libHandle); #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ dlclose(m_libHandle); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ m_libHandle = NULL; } if (threadLocalStorageHandle) #if ITT_PLATFORM==ITT_PLATFORM_WIN TlsFree (threadLocalStorageHandle); #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ pthread_key_delete(threadLocalStorageHandle); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ }
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) { TRACE("(%p, %d, %p)\n", hInstance, Reason, Reserved); switch(Reason) { case DLL_PROCESS_ATTACH: COMDLG32_hInstance = hInstance; DisableThreadLibraryCalls(hInstance); SHELL32_hInstance = GetModuleHandleA("SHELL32.DLL"); /* ITEMIDLIST */ GPA(COMDLG32_PIDL_ILIsEqual, SHELL32_hInstance, (LPCSTR)21L); GPA(COMDLG32_PIDL_ILCombine, SHELL32_hInstance, (LPCSTR)25L); GPA(COMDLG32_PIDL_ILGetNext, SHELL32_hInstance, (LPCSTR)153L); GPA(COMDLG32_PIDL_ILClone, SHELL32_hInstance, (LPCSTR)18L); GPA(COMDLG32_PIDL_ILRemoveLastID, SHELL32_hInstance, (LPCSTR)17L); GPA(COMDLG32_PIDL_ILGetSize, SHELL32_hInstance, (LPCSTR)152L); /* SHELL */ GPA(COMDLG32_SHSimpleIDListFromPathAW, SHELL32_hInstance, (LPCSTR)162); GPA(COMDLG32_SHAlloc, SHELL32_hInstance, (LPCSTR)196L); GPA(COMDLG32_SHFree, SHELL32_hInstance, (LPCSTR)195L); /* for the first versions of shell32 SHGetFolderPathW is in SHFOLDER.DLL */ COMDLG32_SHGetFolderPathW = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFolderPathW"); if (!COMDLG32_SHGetFolderPathW) { SHFOLDER_hInstance = LoadLibraryA("SHFOLDER.DLL"); GPA(COMDLG32_SHGetFolderPathW, SHFOLDER_hInstance,"SHGetFolderPathW"); } break; case DLL_PROCESS_DETACH: if (Reserved) break; if (COMDLG32_TlsIndex != TLS_OUT_OF_INDEXES) TlsFree(COMDLG32_TlsIndex); if(SHFOLDER_hInstance) FreeLibrary(SHFOLDER_hInstance); break; } return TRUE; }
void OsDestroy() { (void)SymCleanup(gDebugSymbolHandle); if (NULL != gInterfaceChangeObserver) { gInterfaceChangeObserver->iShutdown = 1; (void)WSASetEvent(gInterfaceChangeObserver->iShutdownEvent); (void)WaitForSingleObject(gInterfaceChangeObserver->iSem, INFINITE); CloseHandle(gInterfaceChangeObserver->iSem); WSACloseEvent(gInterfaceChangeObserver->iEvent); WSACloseEvent(gInterfaceChangeObserver->iShutdownEvent); (void)closesocket(gInterfaceChangeObserver->iSocket); free(gInterfaceChangeObserver); gInterfaceChangeObserver = NULL; } (void)WSACleanup(); OsMutexDestroy(gMutex); gMutex = kHandleNull; TlsFree(gTlsIndex); }
extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { // 如果使用 lpReserved,请将此移除 UNREFERENCED_PARAMETER(lpReserved); if (dwReason == DLL_PROCESS_ATTACH) { TRACE0("CommonLibrary.DLL 正在初始化!\n"); // 扩展 DLL 一次性初始化 if (!AfxInitExtensionModule(CommonLibraryDLL, hInstance)) return 0; // 将此 DLL 插入到资源链中 // 注意: 如果此扩展 DLL 由 // MFC 规则 DLL (如 ActiveX 控件)隐式链接到, // 而不是由 MFC 应用程序链接到,则需要 // 将此行从 DllMain 中移除并将其放置在一个 // 从此扩展 DLL 导出的单独的函数中。使用此扩展 DLL 的 // 规则 DLL 然后应显式 // 调用该函数以初始化此扩展 DLL。否则, // CDynLinkLibrary 对象不会附加到 // 规则 DLL 的资源链,并将导致严重的 // 问题。 new CDynLinkLibrary(CommonLibraryDLL); } else if (dwReason == DLL_PROCESS_DETACH) { TRACE0("CommonLibrary.DLL 正在终止!\n"); if( common::utility::last_error_key != TLS_OUT_OF_INDEXES) TlsFree( common::utility::last_error_key); // 在调用析构函数之前终止该库 AfxTermExtensionModule(CommonLibraryDLL); } return 1; // 确定 }
BOOL APIENTRY DllMain ( HINSTANCE hinstDLL, /* DLL module handle */ DWORD fdwReason, /* reason called */ LPVOID lpvReserved /* reserved */ ) { switch (fdwReason) { /* the DLL is loading due to process initialization or a call to LoadLibrary */ case DLL_PROCESS_ATTACH: /* allocate a TLS index */ dwTlsIndex = TlsAlloc(); if (dwTlsIndex == 0xFFFFFFFF) return FALSE; /* initialize the index for first thread */ TlsSetValue(dwTlsIndex, NULL); /* initialize GLPK library environment */ lib_init_env(); break; /* the attached process creates a new thread */ case DLL_THREAD_ATTACH: /* initialize the TLS index for this thread */ TlsSetValue(dwTlsIndex, NULL); /* initialize GLPK library environment */ lib_init_env(); break; /* the thread of the attached process terminates */ case DLL_THREAD_DETACH: /* free GLPK library environment */ lib_free_env(); break; /* the DLL is unloading due to process termination or call to FreeLibrary */ case DLL_PROCESS_DETACH: /* free GLPK library environment */ lib_free_env(); /* release the TLS index */ TlsFree(dwTlsIndex); break; default: break; } return TRUE; }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (iv_state_index == -1) return TRUE; if (fdwReason == DLL_PROCESS_DETACH || fdwReason == DLL_THREAD_DETACH) { struct iv_state *st; st = iv_get_state(); if (st != NULL) __iv_deinit(st); } if (fdwReason == DLL_PROCESS_DETACH) { TlsFree(iv_state_index); iv_state_index = -1; } return TRUE; }
/** * Unlike pthreads, the Windows API does not seem to provide a convenient way to * hook a callback onto thread shutdown. However, the Windows portable * executable format does define a concept of thread-local storage callbacks. * Here, we define a function and instruct the linker to set a pointer to that * function in the segment for thread-local storage callbacks. See page 85 of * Microsoft Portable Executable and Common Object File Format Specification: * http://msdn.microsoft.com/en-us/gg463119.aspx * This technique only works for implicit linking (OS loads DLL on demand), not * for explicit linking (user code calls LoadLibrary directly). This effectively * means that we have a known limitation: libhdfs may not work correctly if a * Windows application attempts to use it via explicit linking. * * @param h module handle * @param reason the reason for calling the callback * @param pv reserved, unused */ static void NTAPI tlsCallback(PVOID h, DWORD reason, PVOID pv) { DWORD tlsIndex; switch (reason) { case DLL_THREAD_DETACH: detachCurrentThreadFromJvm(); break; case DLL_PROCESS_DETACH: detachCurrentThreadFromJvm(); tlsIndex = gTlsIndex; gTlsIndex = TLS_OUT_OF_INDEXES; if (!TlsFree(tlsIndex)) { fprintf(stderr, "tlsCallback: TlsFree failed with error %d\n", GetLastError()); } break; default: break; } }
/* * Dll Entry */ extern BOOL APIENTRY WinDivertDllEntry(HANDLE module0, DWORD reason, LPVOID reserved) { HANDLE event; switch (reason) { case DLL_PROCESS_ATTACH: module = module0; if ((windivert_tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) { return FALSE; } // Fallthrough case DLL_THREAD_ATTACH: event = CreateEvent(NULL, FALSE, FALSE, NULL); if (event == NULL) { return FALSE; } TlsSetValue(windivert_tls_idx, (LPVOID)event); break; case DLL_PROCESS_DETACH: event = (HANDLE)TlsGetValue(windivert_tls_idx); if (event != (HANDLE)NULL) { CloseHandle(event); } TlsFree(windivert_tls_idx); break; case DLL_THREAD_DETACH: event = (HANDLE)TlsGetValue(windivert_tls_idx); if (event != (HANDLE)NULL) { CloseHandle(event); } break; } return TRUE; }
/*! This function has to be called atfer the last usage of hpgs. It cleans up internally allocated resources. */ void hpgs_cleanup() { hpgs_font_cleanup(); hpgs_cleanup_plugin_devices(); if (hpgs_reader_prefix) { free(hpgs_reader_prefix); hpgs_reader_prefix = 0; } #ifdef WIN32 TlsFree(tls_handle); HeapDestroy(hHeap); hHeap=0; tls_handle=-1; #else hpgs_clear_error(); pthread_key_delete (key); #endif }
void tss_delete( tss_t key ) { struct _PDCLIB_tss * prev = NULL; struct _PDCLIB_tss * cur = _PDCLIB_tss_first; while(cur) { if(cur == key) { if(prev) { prev->_Next = key->_Next; } else { _PDCLIB_tss_first = key->_Next; } TlsFree(key->_Key); free(key); return; } } // Not actually a TSS key abort(); }
/************************************************************************* * SHLWAPI LibMain * * NOTES * calling oleinitialize here breaks sone apps. */ BOOL WINAPI SHLWAPI_LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { TRACE("0x%x 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad); switch (fdwReason) { case DLL_PROCESS_ATTACH: shlwapi_hInstance = hinstDLL; SHLWAPI_ThreadRef_index = TlsAlloc(); break; case DLL_PROCESS_DETACH: if (SHLWAPI_hshell32) FreeLibrary(SHLWAPI_hshell32); if (SHLWAPI_hwinmm) FreeLibrary(SHLWAPI_hwinmm); if (SHLWAPI_hcomdlg32) FreeLibrary(SHLWAPI_hcomdlg32); if (SHLWAPI_hmpr) FreeLibrary(SHLWAPI_hmpr); if (SHLWAPI_hmlang) FreeLibrary(SHLWAPI_hmlang); if (SHLWAPI_hversion) FreeLibrary(SHLWAPI_hversion); if (SHLWAPI_ThreadRef_index >= 0) TlsFree(SHLWAPI_ThreadRef_index); break; } return TRUE; }
asCThreadManager::~asCThreadManager() { #ifndef AS_NO_THREADS // Deallocate the thread local storage #if defined AS_POSIX_THREADS pthread_key_delete((pthread_key_t)tlsKey); #elif defined AS_WINDOWS_THREADS #if defined(_MSC_VER) && (WINAPI_FAMILY & WINAPI_FAMILY_PHONE_APP) tld = 0; #else TlsFree((DWORD)tlsKey); #endif #endif #else if( tld ) { asDELETE(tld,asCThreadLocalData); } tld = 0; #endif }