static LLBC_NS LLBC_ThreadRtn __LLBC_ThreadMgr_ThreadEntry(LLBC_NS LLBC_ThreadArg arg) { // Get thread arguments. __LLBC_ThreadMgr_Thread_Arg *threadArg = reinterpret_cast<__LLBC_ThreadMgr_Thread_Arg *>(arg); ASSERT(threadArg && "llbc library internal error, threadArg NULL!"); LLBC_NS LLBC_ThreadArg realArg = threadArg->realArg; LLBC_NS LLBC_ThreadProc realProc = threadArg->realProc; LLBC_NS LLBC_Handle threadHandle = threadArg->threadHandle; LLBC_NS LLBC_ThreadManager *threadMgr = threadArg->threadMgr; // Set TLS. LLBC_NS __LLBC_LibTls *tls = LLBC_NS __LLBC_GetLibTls(); tls->coreTls.llbcThread = true; tls->coreTls.threadHandle = threadArg->threadHandle; #if LLBC_TARGET_PLATFORM_NON_WIN32 tls->coreTls.nativeThreadHandle = LLBC_NS LLBC_GetCurrentThread(); #else // LLBC_TARGET_PLATFORM_WIN32 HANDLE pseudoHandle = ::GetCurrentThread(); ::DuplicateHandle(::GetCurrentProcess(), pseudoHandle, ::GetCurrentProcess(), &tls->coreTls.nativeThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS); #endif // LLBC_TARGET_PLATFORM_NON_WIN32 // Delete arg. delete threadArg; // Notify thread manager thread startup. threadMgr->OnThreadStartup(threadHandle); // Call thread proc. LLBC_NS LLBC_ThreadRtn rtn = (*realProc)(realArg); // Notify thread manager thread terminated. threadMgr->OnThreadTerminate(threadHandle); // Cleanup tls. #if LLBC_TARGET_PLATFORM_WIN32 ::CloseHandle(tls->coreTls.nativeThreadHandle); #endif // LLBC_TARGET_PLATFORM_WIN32 LLBC_NS __LLBC_ResetLibTls(); return rtn; }
void __LLBC_CommonCleanup() { // Reset entry thread tls info. #if LLBC_TARGET_PLATFORM_WIN32 __LLBC_LibTls *tls = __LLBC_GetLibTls(); ::CloseHandle(tls->coreTls.nativeThreadHandle); #endif // LLBC_TARGET_PLATFORM_WIN32 __LLBC_ResetLibTls(); // Destroy errors. __LLBC_DestroyErrors(); // Destroy library TLS. __LLBC_DestroyLibTls(); }