📄 ncbithr.cpp
字号:
{{ CFastMutexGuard state_guard(s_ThreadMutex); // Indicate the thread is terminated thread_obj->m_IsTerminated = true; // Schedule the thread object for destruction, if detached if ( thread_obj->m_IsDetached ) { thread_obj->m_SelfRef.Reset(); } }} return 0;}CThread::CThread(void) : m_IsRun(false), m_IsDetached(false), m_IsJoined(false), m_IsTerminated(false), m_ExitData(0){ DoDeleteThisObject();#if defined(HAVE_PTHREAD_SETCONCURRENCY) && defined(NCBI_POSIX_THREADS) // Adjust concurrency for Solaris etc. if (pthread_getconcurrency() == 0) { xncbi_Validate(pthread_setconcurrency(GetCpuCount()) == 0, "CThread::CThread() -- pthread_setconcurrency(2) " "failed"); }#endif}CThread::~CThread(void){#if defined(NCBI_WIN32_THREADS) // close handle if it's not yet closed CFastMutexGuard state_guard(s_ThreadMutex); if ( m_IsRun && m_Handle != NULL ) { CloseHandle(m_Handle); m_Handle = NULL; }#endif}#if defined(NCBI_POSIX_THREADS)extern "C" { typedef TWrapperRes (*FSystemWrapper)(TWrapperArg);}#elif defined(NCBI_WIN32_THREADS)extern "C" { typedef TWrapperRes (WINAPI *FSystemWrapper)(TWrapperArg);}#endifbool CThread::Run(TRunMode flags){ // Do not allow the new thread to run until m_Handle is set CFastMutexGuard state_guard(s_ThreadMutex); // Check xncbi_Validate(!m_IsRun, "CThread::Run() -- called for already started thread"); m_IsDetached = (flags & fRunDetached) != 0;#if defined(NCBI_WIN32_THREADS) // We need this parameter in WinNT - can not use NULL instead! DWORD thread_id; m_Handle = CreateThread(NULL, 0, reinterpret_cast<FSystemWrapper>(Wrapper), this, 0, &thread_id); xncbi_Validate(m_Handle != NULL, "CThread::Run() -- error creating thread"); if ( m_IsDetached ) { CloseHandle(m_Handle); m_Handle = NULL; } else { // duplicate handle to adjust security attributes HANDLE oldHandle = m_Handle; xncbi_Validate(DuplicateHandle(GetCurrentProcess(), oldHandle, GetCurrentProcess(), &m_Handle, 0, FALSE, DUPLICATE_SAME_ACCESS), "CThread::Run() -- error getting thread handle"); xncbi_Validate(CloseHandle(oldHandle), "CThread::Run() -- error closing thread handle"); }#elif defined(NCBI_POSIX_THREADS) pthread_attr_t attr; xncbi_Validate(pthread_attr_init (&attr) == 0, "CThread::Run() - error initializing thread attributes"); if ( ! (flags & fRunUnbound) ) { xncbi_Validate(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "CThread::Run() - error setting thread scope"); } if ( m_IsDetached ) { xncbi_Validate(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "CThread::Run() - error setting thread detach state"); } xncbi_Validate(pthread_create(&m_Handle, &attr, reinterpret_cast<FSystemWrapper>(Wrapper), this) == 0, "CThread::Run() -- error creating thread"); xncbi_Validate(pthread_attr_destroy(&attr) == 0, "CThread::Run() - error destroying thread attributes");#else if (flags & fRunAllowST) { Wrapper(this); } else { xncbi_Validate(0, "CThread::Run() -- system does not support threads"); }#endif // prevent deletion of CThread until thread is finished m_SelfRef.Reset(this); // Indicate that the thread is run m_IsRun = true; return true;}void CThread::Detach(void){ CFastMutexGuard state_guard(s_ThreadMutex); // Check the thread state: it must be run, but not detached yet xncbi_Validate(m_IsRun, "CThread::Detach() -- called for not yet started thread"); xncbi_Validate(!m_IsDetached, "CThread::Detach() -- called for already detached thread"); // Detach the thread#if defined(NCBI_WIN32_THREADS) xncbi_Validate(CloseHandle(m_Handle), "CThread::Detach() -- error closing thread handle"); m_Handle = NULL;#elif defined(NCBI_POSIX_THREADS) xncbi_Validate(pthread_detach(m_Handle) == 0, "CThread::Detach() -- error detaching thread");#endif // Indicate the thread is detached m_IsDetached = true; // Schedule the thread object for destruction, if already terminated if ( m_IsTerminated ) { m_SelfRef.Reset(); }}void CThread::Join(void** exit_data){ // Check the thread state: it must be run, but not detached yet {{ CFastMutexGuard state_guard(s_ThreadMutex); xncbi_Validate(m_IsRun, "CThread::Join() -- called for not yet started thread"); xncbi_Validate(!m_IsDetached, "CThread::Join() -- called for detached thread"); xncbi_Validate(!m_IsJoined, "CThread::Join() -- called for already joined thread"); m_IsJoined = true; }} // Join (wait for) and destroy#if defined(NCBI_WIN32_THREADS) xncbi_Validate(WaitForSingleObject(m_Handle, INFINITE) == WAIT_OBJECT_0, "CThread::Join() -- can not join thread"); DWORD status; xncbi_Validate(GetExitCodeThread(m_Handle, &status) && status != DWORD(STILL_ACTIVE), "CThread::Join() -- thread is still running after join"); xncbi_Validate(CloseHandle(m_Handle), "CThread::Join() -- can not close thread handle"); m_Handle = NULL;#elif defined(NCBI_POSIX_THREADS) xncbi_Validate(pthread_join(m_Handle, 0) == 0, "CThread::Join() -- can not join thread");#endif // Set exit_data value if ( exit_data ) { *exit_data = m_ExitData; } // Schedule the thread object for destruction {{ CFastMutexGuard state_guard(s_ThreadMutex); m_SelfRef.Reset(); }}}void CThread::Exit(void* exit_data){ // Don't exit from the main thread CThread* x_this = GetThreadsTls().GetValue(); xncbi_Validate(x_this != 0, "CThread::Exit() -- attempt to call for the main thread"); {{ CFastMutexGuard state_guard(s_ThreadMutex); x_this->m_ExitData = exit_data; }} // Throw the exception to be caught by Wrapper() throw CExitThreadException();}bool CThread::Discard(void){ CFastMutexGuard state_guard(s_ThreadMutex); // Do not discard after Run() if ( m_IsRun ) { return false; } // Schedule for destruction (or, destroy it right now if there is no // other CRef<>-based references to this object left). m_SelfRef.Reset(this); m_SelfRef.Reset(); return true;}void CThread::OnExit(void){ return;}void CThread::AddUsedTls(CTlsBase* tls){ // Can not use s_ThreadMutex in POSIX since it may be already locked CFastMutexGuard tls_cleanup_guard(s_TlsCleanupMutex); // Get current thread object CThread* x_this = GetThreadsTls().GetValue(); if ( x_this ) { x_this->m_UsedTls.insert(CRef<CTlsBase>(tls)); }}void CThread::GetSystemID(TThreadSystemID* id){#if defined(NCBI_WIN32_THREADS) // Can not use GetCurrentThread() since it also requires // DuplicateHandle() and CloseHandle() to be called for the result. *id = GetCurrentThreadId();#elif defined(NCBI_POSIX_THREADS) *id = pthread_self();#else *id = 0;#endif return;}END_NCBI_SCOPE/* * =========================================================================== * $Log: ncbithr.cpp,v $ * Revision 1000.1 2004/06/01 19:09:26 gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.30 * * Revision 1.30 2004/05/14 13:59:27 gorelenk * Added include of ncbi_pch.hpp * * Revision 1.29 2003/09/17 15:20:46 vasilche * Moved atomic counter swap functions to separate file. * Added CRef<>::AtomicResetFrom(), CRef<>::AtomicReleaseTo() methods. * * Revision 1.28 2003/06/27 17:28:08 ucko * +SwapPointers * * Revision 1.27 2003/05/20 14:23:49 vasilche * Added call to pthread_attr_destroy as memory leak was detected. * * Revision 1.26 2003/05/08 20:50:10 grichenk * Allow MT tests to run in ST mode using CThread::fRunAllowST flag. * * Revision 1.25 2003/04/08 18:41:08 shomrat * Setting the handle to NULL after closing it * * Revision 1.24 2003/03/10 18:57:08 kuznets * iterate->ITERATE * * Revision 1.23 2002/11/04 21:29:04 grichenk * Fixed usage of const CRef<> and CRef<> constructor * * Revision 1.22 2002/09/30 16:53:28 vasilche * Fix typedef on Windows. * * Revision 1.21 2002/09/30 16:32:29 vasilche * Fixed bug with self referenced CThread. * Added bound running flag to CThread. * Fixed concurrency level on POSIX threads. * * Revision 1.20 2002/09/19 20:05:43 vasilche * Safe initialization of static mutexes * * Revision 1.19 2002/09/13 17:00:11 ucko * When using POSIX threads, #include <sys/time.h> for gettimeofday(). * * Revision 1.18 2002/09/13 15:14:49 ucko * Give CSemaphore::TryWait an optional timeout (defaulting to 0) * * Revision 1.17 2002/04/11 21:08:03 ivanov * CVS log moved to end of the file * * Revision 1.16 2002/04/11 20:00:45 ivanov * Returned standard assert() vice CORE_ASSERT() * * Revision 1.15 2002/04/10 18:39:10 ivanov * Changed assert() to CORE_ASSERT() * * Revision 1.14 2001/12/13 19:45:37 gouriano * added xxValidateAction functions * * Revision 1.13 2001/12/12 17:11:23 vakatov * [NCBI_POSIX_THREADS] CSemaphore::Post() -- assert(0) just to make sure * * Revision 1.12 2001/12/11 22:58:16 vakatov * [NCBI_POSIX_THREADS] CSemaphore::Post() -- avoid throwing exception * without unlocking the embracing mutex first * * Revision 1.11 2001/12/10 18:07:55 vakatov * Added class "CSemaphore" -- application-wide semaphore * * Revision 1.10 2001/05/17 15:05:00 lavr * Typos corrected * * Revision 1.9 2001/04/03 18:20:45 grichenk * CThread::Exit() and CThread::Wrapper() redesigned to use * CExitThreadException instead of system functions * * Revision 1.8 2001/03/30 22:57:34 grichenk * + CThread::GetSystemID() * * Revision 1.7 2001/03/27 18:12:35 grichenk * CRWLock destructor releases system resources * * Revision 1.5 2001/03/26 21:45:29 vakatov * Workaround static initialization/destruction traps: provide better * timing control, and allow safe use of the objects which are * either not yet initialized or already destructed. (with A.Grichenko) * * Revision 1.4 2001/03/13 22:43:20 vakatov * Full redesign. * Implemented all core functionality. * Thoroughly tested on different platforms. * * Revision 1.3 2000/12/11 06:48:49 vakatov * Revamped Mutex and RW-lock APIs * * Revision 1.2 2000/12/09 18:41:59 vakatov * Fixed for the extremely smart IRIX MIPSpro73 compiler * * Revision 1.1 2000/12/09 00:04:21 vakatov * First draft: Fake implementation of Mutex and RW-lock API * * =========================================================================== */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -