49 #ifdef NCBI_POSIX_THREADS
50 # include <sys/time.h>
53 # include <sys/prctl.h>
59 #define NCBI_USE_ERRCODE_X Corelib_Threads
219 #if defined(NCBI_WIN32_THREADS)
221 #elif defined(NCBI_POSIX_THREADS)
240 #if defined(NCBI_WIN32_THREADS)
241 if ( TlsFree(
m_Key) ) {
246 #elif defined(NCBI_POSIX_THREADS)
247 if (pthread_key_delete(
m_Key) == 0) {
263 #if defined(NCBI_WIN32_THREADS)
265 #elif defined(NCBI_POSIX_THREADS)
290 "CTlsBase::x_SetValue() -- cannot allocate "
291 "memory for TLS data");
297 #ifdef NCBI_WIN32_THREADS
315 "CTlsBase::x_SetValue() -- error setting value");
339 "CTlsBase::x_Reset() -- error cleaning-up TLS");
387 : m_RefCount(new
int),
388 m_InWrapper(new
bool)
396 : m_RefCount(
prev.m_RefCount),
397 m_InWrapper(
prev.m_InWrapper)
414 if ( !tmp_in_wrapper ) {
416 assert(((
void)(
"CThread::Exit() -- cannot exit thread"), 0));
417 #if defined(NCBI_WIN32_THREADS)
419 #elif defined(NCBI_POSIX_THREADS)
466 static int s_ThreadCount = 0;
467 return ++s_ThreadCount;
473 #if defined(NCBI_THREADS)
485 #if defined(NCBI_THREADS)
490 ERR_POST(
"Can not change main thread ID");
494 #if defined(NCBI_THREADS)
498 if ( !sx_ThreadId ) {
517 TID id = sx_ThreadId;
548 THREAD_CATCH_UNHANDLED_EXCEPTIONS);
549 typedef NCBI_PARAM_TYPE(Thread, Catch_Unhandled_Exceptions) TParamThreadCatchExceptions;
560 "CThread::Wrapper() -- error assigning thread ID");
562 #if defined NCBI_THREAD_PID_WORKAROUND
564 thread_obj->m_ThreadPID =
565 CProcess::sx_GetPid(CProcess::ePID_GetThread);
568 bool catch_all = TParamThreadCatchExceptions::GetDefault();
583 #if defined(NCBI_COMPILER_MSVC) && defined(_DEBUG)
589 NCBI_CATCH_X(1,
"CThread::Wrapper: CThread::Main() failed");
608 #if defined(NCBI_COMPILER_MSVC) && defined(_DEBUG)
614 NCBI_CATCH_X(3,
"CThread::Wrapper: CThread::OnExit() failed");
646 : m_Handle(0), m_IsRun(
false),
649 m_IsTerminated(
false),
651 #
if defined NCBI_THREAD_PID_WORKAROUND
661 #if defined(NCBI_WIN32_THREADS)
677 #if defined(NCBI_POSIX_THREADS)
685 #elif defined(NCBI_WIN32_THREADS)
696 #if defined NCBI_THREAD_PID_WORKAROUND
697 TPid CThread::sx_GetThreadPid(
void)
700 return thread_ptr ? thread_ptr->m_ThreadPID : 0;
704 void CThread::sx_SetThreadPid(
TPid pid)
708 thread_ptr->m_ThreadPID = pid;
714 #define NCBI_THREAD_VALIDATE(cond, error_code, message) \
715 if ( !(cond) ) NCBI_THROW(CThreadException, error_code, message)
733 "CThread::Run() -- called for already started thread");
737 #if defined NCBI_THREAD_PID_WORKAROUND
738 CProcess::sx_GetPid(CProcess::ePID_GetCurrent);
749 #if defined(NCBI_WIN32_THREADS)
755 this, creation_flags, &thread_id);
757 "CThread::Run() -- error creating thread");
760 SetThreadPriority(
m_Handle, THREAD_PRIORITY_BELOW_NORMAL);
772 0,
FALSE, DUPLICATE_SAME_ACCESS),
773 eRunError,
"CThread::Run() -- error getting thread handle");
775 eRunError,
"CThread::Run() -- error closing thread handle");
777 #elif defined(NCBI_POSIX_THREADS)
780 "CThread::Run() - error initializing thread attributes");
782 #if defined(NCBI_OS_BSD) || defined(NCBI_OS_CYGWIN) || defined(NCBI_OS_IRIX)
784 PTHREAD_SCOPE_PROCESS) == 0, eRunError,
785 "CThread::Run() - error setting thread scope");
788 PTHREAD_SCOPE_SYSTEM) == 0, eRunError,
789 "CThread::Run() - error setting thread scope");
794 PTHREAD_CREATE_DETACHED) == 0, eRunError,
795 "CThread::Run() - error setting thread detach state");
798 TParamThreadStackSize::GetDefault()) == 0, eRunError,
799 "Thread::Run() -- error setting stack size");
802 "CThread::Run() -- error creating thread");
805 "CThread::Run() - error destroying thread attributes");
813 "CThread::Run() -- system does not support threads");
839 "CThread::Detach() -- called for not yet started thread");
841 "CThread::Detach() -- called for already detached thread");
844 #if defined(NCBI_WIN32_THREADS)
846 "CThread::Detach() -- error closing thread handle");
848 #elif defined(NCBI_POSIX_THREADS)
850 "CThread::Detach() -- error detaching thread");
869 "CThread::Join() -- called for not yet started thread");
871 "CThread::Join() -- called for detached thread");
873 "CThread::Join() -- called for already joined thread");
878 #if defined(NCBI_WIN32_THREADS)
880 eControlError,
"CThread::Join() -- can not join thread");
883 status !=
DWORD(STILL_ACTIVE), eControlError,
884 "CThread::Join() -- thread is still running after join");
886 "CThread::Join() -- can not close thread handle");
888 #elif defined(NCBI_POSIX_THREADS)
890 "CThread::Join() -- can not join thread");
911 "CThread::Exit() -- attempt to call for the main thread");
952 #if defined(NCBI_OS_LINUX) && defined(PR_SET_NAME)
955 prctl(PR_SET_NAME, (
unsigned long)name.
data(), 0, 0, 0);
977 if ( !
IsMain() )
return false;
981 unsigned long to = 0;
982 unsigned long q = 10;
996 switch (GetErrCode()) {
999 case eOther:
return "eOther";
~CExitThreadException(void)
CExitThreadException(void)
T & Get(void)
Create the variable if not created yet, return the reference.
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
CTimeout – Timeout interval.
iterator_bool insert(const value_type &val)
static void cleanup(void)
static DLIST_TYPE *DLIST_NAME() prev(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
static void SetRequestContext(CRequestContext *ctx)
Shortcut to CDiagContextThreadData::GetThreadData().SetRequestContext()
static CRequestContext & GetRequestContext(void)
Shortcut to CDiagContextThreadData::GetThreadData().GetRequestContext()
CRef< CRequestContext > Clone(void) const
Copy current request context to a new one.
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
#define NCBI_CATCH_ALL_X(err_subcode, message)
#define NCBI_CATCH_X(err_subcode, message)
Catch CExceptions as well with default error code and given error subcode placed in diagnostics.
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
virtual void DoDeleteThisObject(void)
Mark this object as allocated in heap – object can be deleted.
void AddReference(void) const
Add reference to object.
void Reset(void)
Reset reference object.
void RemoveReference(void) const
Remove reference to object.
bool Referenced(void) const THROWS_NONE
Check if object is referenced.
@ eParam_NoThread
Do not use per-thread values.
pid_t TPid
Process identifier (PID) and process handle.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
const char * data(void) const
Return a pointer to the array represented.
void * m_ExitData
as returned by Main() or passed to Exit()
void * TWrapperArg
Define platform-dependent argument wrapper.
static bool WaitForAllThreads(void)
bool Run(TRunMode flags=fRunDefault)
Run the thread.
TThreadHandle m_Handle
platform-dependent thread handle
static void Exit(void *exit_data)
Cancel current thread.
void Register(CTlsBase *tls)
bool m_IsTerminated
if Exit() was called for the thread
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
bool x_DeleteTlsData(ECleanupMode mode=eCleanup_Toolkit)
Deletes STlsData* structure and managed pointer Returns true if CTlsBase must be deregistered from cu...
bool m_Initialized
Indicates if thread data initialized.
static void GetSystemID(TThreadSystemID *id)
Get system ID of the current thread - for internal use only.
static CUsedTlsBases & GetUsedTlsBases(void)
Get the list of used TLS-es for the current thread.
ENativeThreadCleanup
Flag indicating if cleanup function should be called when using native threads rather than CThread.
ECleanupMode
Flag telling which code has called TLS cleanup.
bool Discard(void)
If the thread has not been Run() yet, then schedule the thread object for destruction,...
static CTimeout sm_WaitForThreadsTimeout
void Detach(void)
Inform the thread that user does not need to wait for its termination.
static CStaticTls< CUsedTlsBases > sm_UsedTlsBases
FCleanupBase m_CleanupFunc
void ClearAll(CTlsBase::ECleanupMode mode=CTlsBase::eCleanup_Toolkit)
The function is called before thread termination to cleanup data stored in the TLS.
static void Init(void)
Init TLS, call before creating thread.
virtual void OnExit(void)
Override this to execute finalization code.
virtual ~CThread(void)
To be called only internally! NOTE: destructor of the derived (user-provided) class should be declare...
static void SetCurrentThreadName(const CTempString &)
Set name for the current thread.
bool m_IsDetached
if the thread is detached
pthread_key_t TTlsKey
Define internal TLS key type.
void x_Destroy(void)
Destroy thread data.
void x_Init(void)
Initialize thread data.
CThread(void)
Constructor.
unsigned int TID
Get ID of current thread.
CRef< CRequestContext > m_ParentRequestContext
static void InitializeMainThreadId(void)
Initialize main thread's TID.
bool m_IsRun
if Run() was called for the thread
bool m_AutoDestroy
Indicates if object should be destroyed in destructor.
static void x_CleanupThreadCallback(void *ptr)
static TWrapperRes Wrapper(TWrapperArg arg)
Function to use (internally) as the thread's startup function.
static void CleanupAndDeleteTlsData(void *data, ECleanupMode mode=eCleanup_Toolkit)
static void ClearAllCurrentThread(CTlsBase::ECleanupMode mode=CTlsBase::eCleanup_Toolkit)
Clear used TLS-es for the current thread.
void x_Reset(void)
Helper method to reset thread data.
virtual void * Main(void)=0
Derived (user-created) class must provide a real thread function.
void x_SetValue(void *value, FCleanupBase cleanup, void *cleanup_data, ENativeThreadCleanup native)
Helper method to set thread data.
void x_InitializeThreadId(void)
initalize new thread id, must be called from Wrapper().
void SetValue(TValue *value, FCleanup cleanup=0, void *cleanup_data=0, CTlsBase::ENativeThreadCleanup native=CTlsBase::eSkipCleanup)
void * TWrapperRes
Define platform-dependent result wrapper.
int TRunMode
Bitwise OR'd flags for thread creation passed to Run().
pthread_t TThreadSystemID
Define platform-dependent thread ID type.
static void SetWaitForAllThreadsTimeout(const CTimeout &timeout)
Set timeout for stopping all threads on application exit.
static atomic< unsigned int > sm_ThreadsCount
Total amount of threads.
bool m_IsJoined
if Join() was called for the thread
static void CleanupTlsData(void *data, ECleanupMode mode=eCleanup_Toolkit)
void Deregister(CTlsBase *tls)
static CThread * GetCurrentThread(void)
Get current CThread object (or NULL, if main thread)
CRef< CThread > m_SelfRef
"this" – to avoid premature destruction
void Join(void **exit_data=0)
Wait for the thread termination.
ENativeThreadCleanup m_Native
STlsData * x_GetTlsData(void) const
Helper method to get the STlsData*.
static TThreadSystemID GetCurrentThreadSystemID(void)
Get the current thread ID.
@ eControlError
Failed to control thread's state.
@ eOther
Other thread errors.
@ eRunError
Failed to run thread.
@ fRunCloneRequestContext
Clone parent's request context and pass it to the new thread.
@ fRunAllowST
Allow threads to run in single thread builds.
@ fRunUnbound
Run thread in a N:1 thread:LPW mode.
@ fRunNice
Run thread with low priority (MS-Win only)
@ fRunDetached
Run the thread detached (non-joinable)
@ eCleanup_Native
Cleanup is performed by thread_local destructor.
double Elapsed(void) const
Return time elapsed since first Start() or last Restart() call (in seconds).
unsigned long GetAsMilliSeconds(void) const
Get as number of milliseconds.
@ eStart
Start timer immediately after creating.
#define HANDLE
An abstraction for a file handle.
unsigned int
A callback function used to compare two keys in a database.
Definition of all error codes used in corelib (xncbi.lib).
if(yy_accept[yy_current_state])
const struct ncbi::grid::netcache::search::fields::KEY key
const GenericPointer< typename T::ValueType > T2 value
#define FALSE
bool replacment for C indicating false.
void SleepMilliSec(unsigned long ml_sec, EInterruptOnSignal onsignal=eRestartOnSignal)
#define xncbi_VerifyAndErrorReport(expression)
#define xncbi_ValidatePthread(expression, expected_value, message)
#define xncbi_Validate(expression, message)
static bool sm_MainThreadIdInitialized
CThread::TID sx_GetMainThreadId()
static DECLARE_TLS_VAR(CThread *, sx_ThreadPtr)
DEFINE_STATIC_MUTEX(s_TlsCleanupMutex)
TWrapperRes(* FSystemWrapper)(TWrapperArg)
static void s_CleanupUsedTlsBases(CUsedTlsBases *tls, void *)
DEFINE_STATIC_FAST_MUTEX(s_ThreadMutex)
void s_TlsSetValue(TTlsKey &key, void *data, const char *err_message)
static int sx_GetNextThreadId(void)
#define NCBI_THREAD_VALIDATE(cond, error_code, message)
void sx_SetMainThreadId(CThread::TID id)
NCBI_PARAM_DEF_EX(bool, Thread, Catch_Unhandled_Exceptions, true, 0, THREAD_CATCH_UNHANDLED_EXCEPTIONS)
NCBI_PARAM_DECL(bool, Thread, Catch_Unhandled_Exceptions)
TWrapperRes ThreadWrapperCaller(TWrapperArg arg)
static TWrapperRes ThreadWrapperCallerImpl(TWrapperArg arg)
static const CThread::TID kMainThreadId
static CSafeStatic< CUsedTlsBases > s_MainUsedTlsBases(0, s_CleanupMainUsedTlsBases, CSafeStaticLifeSpan::eLifeSpan_Long)
static CThread::TID sx_MainThreadId
static void s_CleanupMainUsedTlsBases(CUsedTlsBases &tls)
typedef NCBI_PARAM_TYPE(Thread, Catch_Unhandled_Exceptions) TParamThreadCatchExceptions
Defines CRequestContext class for NCBI C++ diagnostic API.
Internal structure to store all three pointers in the same TLS.
~SNativeThreadTlsCleanup(void)