static void __FiniSema4s( void ) // called from finalizer /******************************/ { int i; _CloseSemaphore( &IOBSemaphore ); for( i = 0; i < MAX_SEMAPHORE; i++ ) { _CloseSemaphore( &FileSemaphores[ i ] ); } #if defined( __NT__ ) _CloseSemaphore( &FListSemaphore ); __NTFreeCriticalSection(); #endif #if !defined( __QNX__ ) __FiniThreadProcessing(); #if !defined( __OS2_286__ ) // All thread data areas freed, including main process thread data // so mark first thread data pointer null. Note that OS/2 1.x does // not have __FirstThreadData at all. __FirstThreadData = NULL; #endif #endif #if !defined( __NETWARE__ ) _heapshrink(); _CloseSemaphore( &NHeapSemaphore ); _CloseSemaphore( &FHeapSemaphore ); #endif #if !defined( _M_I86 ) _CloseSemaphore( &TDListSemaphore ); _CloseSemaphore( &InitSemaphore ); // After closing InitSemaphore, we need to reset the sem access routines to // the dummy ones; someone may still want semaphore protection during shutdown // processing but since threading is gone now, there should be no reentrancy // problems __AccessSema4 = &nullSema4Rtn; __ReleaseSema4 = &nullSema4Rtn; __CloseSema4 = &nullSema4Rtn; #if !defined( __NETWARE__ ) _AccessNHeap = &__NullAccHeapRtn; _AccessFHeap = &__NullAccHeapRtn; _ReleaseNHeap = &__NullAccHeapRtn; _ReleaseFHeap = &__NullAccHeapRtn; #endif #if defined( __NT__ ) __NTDeleteCriticalSection(); __NTThreadFini(); #endif #if defined (_NETWARE_LIBC) __LibCThreadFini(); #endif #endif }
static void __ThreadExit() /************************/ { __LibCRemoveThread( TRUE ); __LibCThreadFini(); }