/* Crash-conditions-safe: */ void InitializePidThreadHelpers() { static bool bInitialized = false; if( bInitialized ) return; bInitialized = true; g_bUsingNPTL = UsingNPTL(); }
/* Hook up events to fatal signals, so we can clean up if we're killed. */ void SignalHandler::OnClose( handler h ) { if( saved_sigs == NULL ) { saved_sigs = new SaveSignals; bool bUseAltSigStack = true; #if defined(LINUX) /* Linuxthreads (pre-NPTL) sigaltstack is broken. */ if( !UsingNPTL() ) bUseAltSigStack = false; #endif /* Allocate a separate signal stack. This makes the crash handler work * if we run out of stack space. */ const int AltStackSize = 1024*64; void *p = NULL; if( bUseAltSigStack ) p = CreateStack( AltStackSize ); if( p != NULL ) { stack_t ss; ss.ss_sp = (char*)p; /* cast for Darwin */ ss.ss_size = AltStackSize; ss.ss_flags = 0; if( sigaltstack( &ss, NULL ) == -1 ) { LOG->Info( "sigaltstack failed: %s", strerror(errno) ); p = NULL; /* no SA_ONSTACK */ } } struct sigaction sa; sa.sa_flags = 0; if( p != NULL ) sa.sa_flags |= SA_ONSTACK; sa.sa_flags |= SA_NODEFER; sa.sa_flags |= SA_SIGINFO; sigemptyset(&sa.sa_mask); /* Set up our signal handlers. */ sa.sa_sigaction = SigHandler; for( int i = 0; signals[i] != -1; ++i ) sigaction( signals[i], &sa, NULL ); /* Block SIGPIPE, so we get EPIPE. */ sa.sa_handler = SIG_IGN; sigaction( SIGPIPE, &sa, NULL ); } handlers.push_back(h); }
static void TestTLS() { /* TLS won't work on older threads libraries, and may crash. */ if( !UsingNPTL() ) return; /* TLS won't work on older Linux kernels. Do a simple check. */ g_iTestTLS = 1; RageThread TestThread; TestThread.SetName( "TestTLS" ); TestThread.Create( TestTLSThread, NULL ); TestThread.Wait(); if( g_iTestTLS == 1 ) RageThread::SetSupportsTLS( true ); }