// $Id: GThread.h 2799 2012-06-28 01:02:38Z matevz $ // Copyright (C) 1999-2008, Matevz Tadel. All rights reserved. // This file is part of GLED, released under GNU General Public License version 2. // For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/. #ifndef GledCore_GThread_H #define GledCore_GThread_H #include #include #include // This wrong ... need internal state class. #ifdef __CINT__ typedef unsigned long int pthread_t; typedef unsigned int pthread_key_t; #else #include #include #endif class GSignal; typedef void* (*GThread_foo)(void*); typedef void (*GThread_cu_foo)(void*); typedef void (*GThread_sh_foo)(GSignal*); class SaturnInfo; class ZMirEmittingEntity; class ZMIR; class TThread; class GThread { friend class Gled; friend class Saturn; friend class Mountain; friend class ZKing; friend class ZQueen; public: enum CState { CS_Enable, CS_Disable }; enum CType { CT_Async, CT_Deferred }; enum Signal { SigUNDEF = -1, SigMIN = 0, SigHUP = 1, SigINT = 2, SigQUIT = 3, SigILL = 4, SigTRAP = 5, SigABRT = 6, SigBUS = 7, SigFPE = 8, SigKILL = 9, SigUSR1 = 10, SigSEGV = 11, SigUSR2 = 12, SigPIPE = 13, SigALRM = 14, SigTERM = 15, SigXXX1 = 16, SigCHLD = 17, SigCONT = 18, SigSTOP = 19, SigTSTP = 20, SigTTIN = 21, SigTTOU = 22, SigURG = 23, SigXCPU = 24, SigXFSZ = 25, SigVTALRM= 26, SigPROF = 27, SigWINCH = 28, SigIO = 29, SigXXX2 = 30, SigSYS = 31, SigMAX = 32, SigMAXRT = 65 }; // from signum.h on Linux; STKFLT, PWR discarded from Linux; EMT, INFO from OSX. enum RState { RS_Incubating, RS_Spawning, RS_Running, RS_Terminating, RS_Finished, RS_ErrorSpawning }; enum TerminalPolicy { TP_ThreadExit, TP_GledExit, TP_SysExit }; class CancelDisabler { CState mExCancelState; public: CancelDisabler() { mExCancelState = CancelOff(); } ~CancelDisabler() { SetCancelState(mExCancelState); } }; class CancelEnabler { CState mExCancelState; public: CancelEnabler() { mExCancelState = CancelOn(); } ~CancelEnabler() { SetCancelState(mExCancelState); } }; private: class Cleanup { GThread_cu_foo mFoo; void* mArg; public: Cleanup(GThread_cu_foo f, void* a) : mFoo(f), mArg(a) {} void Execute() { (mFoo)(mArg); } }; typedef list lCleanup_t; class OwnerChanger { ZMirEmittingEntity* m_owner; public: OwnerChanger(ZMirEmittingEntity* o) { GThread* s = Self(); m_owner = s->get_owner(); s->set_owner(o); } ~OwnerChanger() { GThread::Self()->set_owner(m_owner); } }; class MIRChanger { ZMIR* m_mir; public: MIRChanger(ZMIR* m) { GThread* s = Self(); m_mir = s->get_mir(); s->set_mir(m); } ~MIRChanger() { GThread::Self()->set_mir(m_mir); } }; typedef map mPThr2GThr_t; typedef map::iterator mPThr2GThr_i; typedef list lpGThread_t; typedef list::iterator lpGThread_i; typedef vector vSigHandlers_t; static GThread *sMainThread; static int sThreadCount; static mPThr2GThr_t sThreadMap; static lpGThread_t sThreadList; static GMutex sContainerLock; static GMutex sDetachCtrlLock; static int sMinStackSize; // Thread state / internals RState mRunningState; // X{g} int mIndex; // X{g} lpGThread_i mThreadListIt; pthread_t mId; // X{g} This will become GThreadInternalRep* // Root's thread representation. TThread *mRootTThread; // Parameters of thread to be spawned. TString mName; // X{Gs} GThread_foo mStartFoo; // X{gs} void* mStartArg; // X{gs} lCleanup_t mCleanups; bool bDetached; bool bDetachOnExit; // X{gs} int mNice; // X{gs} int mStackSize; // X{gs} // Signal handlers GThread_sh_foo mSigHandlerDefault; vSigHandlers_t mSigHandlerVector; void *mTerminalContext; int mTerminalSignal; TerminalPolicy mTerminalPolicy; // TSD-like members ZMirEmittingEntity *mOwner; ZMIR *mMIR; void set_owner(ZMirEmittingEntity* owner) { mOwner = owner; } ZMirEmittingEntity* get_owner() const { return mOwner; } void set_mir(ZMIR* mir) { mMIR = mir; } ZMIR* get_mir() const { return mMIR; } static pthread_key_t TSD_Self; static GThread *sInvalidPtr; static int sSigMap[SigMAX]; static void* thread_spawner(void* arg); static void thread_reaper(void* arg); GThread(const Text_t* name); public: GThread(const Text_t* name, GThread_foo foo, void* arg=0, bool detached=false, bool detach_on_exit=false); virtual ~GThread(); void CleanupPush(GThread_cu_foo foo, void* arg); void CleanupPop(bool execute_p); int Spawn(); int Join(void** tret=0); int Kill(Signal signal=SigSTOP); int Cancel(); int Detach(); bool IsDetached() const; bool ClearDetachOnExit(); void ClearRootTThreadRepresentation(); TerminalPolicy GetTerminalPolicy() const { return mTerminalPolicy; } void SetTerminalPolicy(TerminalPolicy tp) { mTerminalPolicy = tp; } static CState SetCancelState(CState s); static CState CancelOn() { return SetCancelState(CS_Enable); } static CState CancelOff() { return SetCancelState(CS_Disable); } static CType SetCancelType(CType t); static int Yield(); static void TestCancel(); static void Exit(void* ret=0); static GThread* Self(); static ZMirEmittingEntity* Owner(); static ZMIR* MIR(); static void BlockAllSignals(); static void UnblockCpuExceptionSignals(bool unblock_fpe); static void BlockSignal(Signal sig); static void UnblockSignal(Signal sig); static GThread_sh_foo SetDefaultSignalHandler(GThread_sh_foo foo); static GThread_sh_foo SetSignalHandler(Signal sig, GThread_sh_foo foo, bool unblock=false); static void TheSignalHandler(GSignal* sig); static void ToRootsSignalHandler(GSignal* sig); static void ListThreads(); static void ListSignalState(); static void CancelAllThreads(bool join_p); static GThread* InitMain(); static void FiniMain(); static int GetMinStackSize(); static void SetMinStackSize(int ss); static const char* RunningStateName(RState state); static const char* SignalName(Signal sig); static Signal SysToGledSignal(Int_t sys_sig); static bool IsValidPtr(GThread* thr) { return thr != 0 && thr != sInvalidPtr; } static void InvalidatePtr(GThread*& thr) { thr = sInvalidPtr; } #include "GThread.h7" ClassDef(GThread, 0); }; // endclass GThread #ifndef __CINT__ class GSignal { public: GSignal(int sid, siginfo_t* sinfo, void* sctx); GThread::Signal fSignal; int fSysSignal; siginfo_t *fSigInfo; void *fContext; }; #endif #endif