TPid CProcess::sx_GetPid(EGetPidFlag flag) { if ( flag == ePID_GetThread ) { // Return real PID, do not cache it. return getpid(); } DEFINE_STATIC_FAST_MUTEX(s_GetPidMutex); static TPid s_CurrentPid = 0; static TPid s_ParentPid = 0; if (CThread::GetSelf() == 0) { // For main thread always force caching of PIDs CFastMutexGuard guard(s_GetPidMutex); s_CurrentPid = getpid(); s_ParentPid = getppid(); } else { // For child threads update cached PIDs only if there was a fork // First call is always from the main thread (explicit or through // CThread::Run()), s_CurrentPid must be != 0 in any child thread. _ASSERT(s_CurrentPid); TPid pid = getpid(); TPid thr_pid = CThread::sx_GetThreadPid(); if (thr_pid && thr_pid != pid) { // Thread's PID has changed - fork detected. // Use current PID and PPID as globals. CThread::sx_SetThreadPid(pid); CFastMutexGuard guard(s_GetPidMutex); s_CurrentPid = pid; s_ParentPid = getppid(); } } return flag == ePID_GetCurrent ? s_CurrentPid : s_ParentPid; }
static TLastNewPtrMultiple& sx_GetLastNewPtrMultiple(void) { #ifdef NCBI_NO_THREADS return s_LastNewPtrMultiple; #else if ( !s_LastNewPtrMultiple_key ) { DEFINE_STATIC_FAST_MUTEX(s_InitMutex); NCBI_NS_NCBI::CFastMutexGuard guard(s_InitMutex); if ( !s_LastNewPtrMultiple_key ) { TTlsKey key = 0; do { # ifdef NCBI_WIN32_THREADS _VERIFY((key = TlsAlloc()) != DWORD(-1)); # else _VERIFY(pthread_key_create(&key, sx_EraseLastNewPtrMultiple)==0); # endif } while ( !key ); # ifndef NCBI_WIN32_THREADS pthread_setspecific(key, 0); # endif s_LastNewPtrMultiple_key = key; } } TLastNewPtrMultiple* set; # ifdef NCBI_WIN32_THREADS set = (TLastNewPtrMultiple*)TlsGetValue(s_LastNewPtrMultiple_key); # else set = (TLastNewPtrMultiple*)pthread_getspecific(s_LastNewPtrMultiple_key); # endif if ( !set ) { set = new TLastNewPtrMultiple(); # ifdef NCBI_WIN32_THREADS TlsSetValue(s_LastNewPtrMultiple_key, set); # else pthread_setspecific(s_LastNewPtrMultiple_key, set); # endif } return *set; #endif }
void CTestDiagApp::x_PrintMessages(int test_number, int idx, const char* module, const char* nclass, const char* function) { string location = string(module) + "::" + nclass + "::" + function + "()"; string postmsg = location + " in ERR_POST"; string exceptmsg = location + " in the one level exception"; string secondmsg = location + " in the two levels exception"; if (idx == 0) { m_Messages[ TCase( test_number, 0 ) ] = postmsg; m_Messages[ TCase( test_number, 1 ) ] = exceptmsg; m_Messages[ TCase( test_number, 2 ) ] = secondmsg; } // ERR_POST ERR_POST(x_MakeMessage(postmsg, idx, TCase(test_number,0)) << MDiagModule(module) << MDiagClass(nclass) << MDiagFunction(function)); // one level exception try { NCBI_EXCEPTION_VAR(expt, CException, eUnknown, "exception"); expt.SetModule(module); expt.SetClass(nclass); expt.SetFunction(function); NCBI_EXCEPTION_THROW(expt); } catch (const CException& ex) { NCBI_REPORT_EXCEPTION(x_MakeMessage(exceptmsg, idx, TCase(test_number, 1)), ex); } #if defined(NCBI_COMPILER_WORKSHOP) # if NCBI_COMPILER_VERSION == 530 || NCBI_COMPILER_VERSION == 550 // Workshop 5.3 and 5.5 have MT-unsafe throw. To avoid test failures // use mutex. DEFINE_STATIC_FAST_MUTEX(s_ThrowMutex); CFastMutexGuard guard(s_ThrowMutex); # endif #endif // two level exceptions try { try { NCBI_EXCEPTION_VAR(expt, CException, eUnknown, "exception1"); expt.SetModule(module); expt.SetClass(nclass); expt.SetFunction(function); NCBI_EXCEPTION_THROW(expt); } catch (const CException& ex) { NCBI_EXCEPTION_VAR_EX(e2, &ex, CException, eUnknown, "exception2"); e2.SetModule(module); e2.SetClass(nclass); e2.SetFunction(function); NCBI_EXCEPTION_THROW(e2); } } catch (const CException& ex) { NCBI_REPORT_EXCEPTION(x_MakeMessage(secondmsg, idx, TCase(test_number, 2)), ex); } }