// // Registers cleanup handler, sets cancel type and state, and excecutes the thread specific // cleanup handler. This function will be called in the Standalone.cpp for regression // testing. When OpenGL applications are run with the driver code, Linux OS does the // thread cleanup. // void OS_CleanupThreadData(void) { #ifdef __ANDROID__ DetachThread(); #else int old_cancel_state, old_cancel_type; void *cleanupArg = NULL; // // Set thread cancel state and push cleanup handler. // pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state); pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg); // // Put the thread in deferred cancellation mode. // pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type); // // Pop cleanup handler and execute it prior to unregistering the cleanup handler. // pthread_cleanup_pop(1); // // Restore the thread's previous cancellation mode. // pthread_setcanceltype(old_cancel_state, NULL); #endif }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: if (!InitProcess()) return FALSE; break; case DLL_THREAD_ATTACH: if (!InitThread()) return FALSE; break; case DLL_THREAD_DETACH: if (!DetachThread()) return FALSE; break; case DLL_PROCESS_DETACH: DetachProcess(); break; default: assert(0 && "DllMain(): Reason for calling DLL Main is unknown"); return FALSE; } return TRUE; }
bool DetachProcess() { bool success = true; if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) return true; ShFinalize(); success = DetachThread(); FreePoolIndex(); OS_FreeTLSIndex(ThreadInitializeIndex); ThreadInitializeIndex = OS_INVALID_TLS_INDEX; return success; }
void C_DECL Hlsl2Glsl_Shutdown() { if (s_ThreadInitialized == OS_INVALID_TLS_INDEX) return; if (PerProcessGPA) { SymbolTables[EShLangVertex].pop(); SymbolTables[EShLangFragment].pop(); PerProcessGPA->popAll(); delete PerProcessGPA; PerProcessGPA = NULL; } DetachThread(); FreePoolIndex(); FreeParseContextIndex(); OS_FreeTLSIndex(s_ThreadInitialized); s_ThreadInitialized = OS_INVALID_TLS_INDEX; }
// Destructor CPostableObject::~CPostableObject() { DetachThread(); }
// // Wrapper for Linux call to DetachThread. This is required as pthread_cleanup_push() expects // the cleanup routine to return void. // void DetachThreadLinux(void *) { DetachThread(); }
DWORD WINAPI STREAMSRVTCPThrProc(LPVOID lpParam) { #else void* STREAMSRVTCPThrProc(void* lpParam) { #endif int EndThread = 0; struct THRPARAMS { SRVTCP* pSRVTCP; int (*OnLoop)(SRVTCP*, SOCKET, void*); void* OnLoopParams; int (*OnNewCli)(SRVTCP*, SOCKET, void*); void* OnNewCliParams; int (*OnCliReq)(SRVTCP*, SOCKET, void*); void* OnCliReqParams; int TooManyConnectionsAction; }; struct THRPARAMS* pParams = (struct THRPARAMS*)lpParam; int NbConnections = 0; // Copy of the thread parameters in local variables SRVTCP* pSRVTCP = pParams->pSRVTCP; int (*OnLoop)(SRVTCP*, SOCKET, void*) = pParams->OnLoop; void* OnLoopParams = pParams->OnLoopParams; int (*OnNewCli)(SRVTCP*, SOCKET, void*) = pParams->OnNewCli; void* OnNewCliParams = pParams->OnNewCliParams; SOCKET ClientSocket = INVALID_SOCKET; // New client socket THREAD_IDENTIFIER ThrId = 0; // Client thread ID struct CLITHRPARAMS { SRVTCP* pSRVTCP; SOCKET ClientSocket; int (*OnLoop)(SRVTCP*, SOCKET, void*); void* OnLoopParams; int (*OnNewCli)(SRVTCP*, SOCKET, void*); void* OnNewCliParams; }; struct CLITHRPARAMS params; // Main loop of the server. do { if ( (AcceptTCP(pSRVTCP->ListenSocket, &ClientSocket) == EXIT_SUCCESS)&& // New incoming connection (SetSockOptTCP(ClientSocket, 1, 10000) == EXIT_SUCCESS) // Setting timeouts for the client socket ) { // Client thread parameters params.pSRVTCP = pSRVTCP; params.ClientSocket = ClientSocket; params.OnLoop = OnLoop; params.OnLoopParams = OnLoopParams; params.OnNewCli = OnNewCli; params.OnNewCliParams = OnNewCliParams; // Creates a thread for the new client if ( (CreateDefaultThread(STREAMSRVTCPLoopCliThrProc, ¶ms, &ThrId) != EXIT_SUCCESS)|| (DetachThread(ThrId) != EXIT_SUCCESS) ) { // Disconnect the client as it can not be handled ShutdownTCP(&ClientSocket, SD_BOTH); DisconnectTCP(&ClientSocket); } } mSleep(100); memcpy_ts(&EndThread, &pSRVTCP->EndThread, sizeof(int), &pSRVTCP->CSEndThread); // Thread-safe copy } while (!EndThread); // Waits for the client threads to terminate do { mSleep(1000); memcpy_ts(&NbConnections, &pSRVTCP->NbConnections, sizeof(int), &pSRVTCP->CSNbConnections); // Thread-safe copy } while (NbConnections > 0); return 0; }