ROOT logo
// $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 <Gled/GledTypes.h>
#include <Gled/GMutex.h>
#include <map>

// This wrong ... need internal state class.
#ifdef __CINT__
typedef unsigned long int pthread_t;
typedef unsigned int      pthread_key_t;
#else
#include <pthread.h>
#include <signal.h>
#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<Cleanup> 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<pthread_t, GThread*>           mPThr2GThr_t;
  typedef map<pthread_t, GThread*>::iterator mPThr2GThr_i;

  typedef list<GThread*>           lpGThread_t;
  typedef list<GThread*>::iterator lpGThread_i;

  typedef vector<GThread_sh_foo>   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
 GThread.h:1
 GThread.h:2
 GThread.h:3
 GThread.h:4
 GThread.h:5
 GThread.h:6
 GThread.h:7
 GThread.h:8
 GThread.h:9
 GThread.h:10
 GThread.h:11
 GThread.h:12
 GThread.h:13
 GThread.h:14
 GThread.h:15
 GThread.h:16
 GThread.h:17
 GThread.h:18
 GThread.h:19
 GThread.h:20
 GThread.h:21
 GThread.h:22
 GThread.h:23
 GThread.h:24
 GThread.h:25
 GThread.h:26
 GThread.h:27
 GThread.h:28
 GThread.h:29
 GThread.h:30
 GThread.h:31
 GThread.h:32
 GThread.h:33
 GThread.h:34
 GThread.h:35
 GThread.h:36
 GThread.h:37
 GThread.h:38
 GThread.h:39
 GThread.h:40
 GThread.h:41
 GThread.h:42
 GThread.h:43
 GThread.h:44
 GThread.h:45
 GThread.h:46
 GThread.h:47
 GThread.h:48
 GThread.h:49
 GThread.h:50
 GThread.h:51
 GThread.h:52
 GThread.h:53
 GThread.h:54
 GThread.h:55
 GThread.h:56
 GThread.h:57
 GThread.h:58
 GThread.h:59
 GThread.h:60
 GThread.h:61
 GThread.h:62
 GThread.h:63
 GThread.h:64
 GThread.h:65
 GThread.h:66
 GThread.h:67
 GThread.h:68
 GThread.h:69
 GThread.h:70
 GThread.h:71
 GThread.h:72
 GThread.h:73
 GThread.h:74
 GThread.h:75
 GThread.h:76
 GThread.h:77
 GThread.h:78
 GThread.h:79
 GThread.h:80
 GThread.h:81
 GThread.h:82
 GThread.h:83
 GThread.h:84
 GThread.h:85
 GThread.h:86
 GThread.h:87
 GThread.h:88
 GThread.h:89
 GThread.h:90
 GThread.h:91
 GThread.h:92
 GThread.h:93
 GThread.h:94
 GThread.h:95
 GThread.h:96
 GThread.h:97
 GThread.h:98
 GThread.h:99
 GThread.h:100
 GThread.h:101
 GThread.h:102
 GThread.h:103
 GThread.h:104
 GThread.h:105
 GThread.h:106
 GThread.h:107
 GThread.h:108
 GThread.h:109
 GThread.h:110
 GThread.h:111
 GThread.h:112
 GThread.h:113
 GThread.h:114
 GThread.h:115
 GThread.h:116
 GThread.h:117
 GThread.h:118
 GThread.h:119
 GThread.h:120
 GThread.h:121
 GThread.h:122
 GThread.h:123
 GThread.h:124
 GThread.h:125
 GThread.h:126
 GThread.h:127
 GThread.h:128
 GThread.h:129
 GThread.h:130
 GThread.h:131
 GThread.h:132
 GThread.h:133
 GThread.h:134
 GThread.h:135
 GThread.h:136
 GThread.h:137
 GThread.h:138
 GThread.h:139
 GThread.h:140
 GThread.h:141
 GThread.h:142
 GThread.h:143
 GThread.h:144
 GThread.h:145
 GThread.h:146
 GThread.h:147
 GThread.h:148
 GThread.h:149
 GThread.h:150
 GThread.h:151
 GThread.h:152
 GThread.h:153
 GThread.h:154
 GThread.h:155
 GThread.h:156
 GThread.h:157
 GThread.h:158
 GThread.h:159
 GThread.h:160
 GThread.h:161
 GThread.h:162
 GThread.h:163
 GThread.h:164
 GThread.h:165
 GThread.h:166
 GThread.h:167
 GThread.h:168
 GThread.h:169
 GThread.h:170
 GThread.h:171
 GThread.h:172
 GThread.h:173
 GThread.h:174
 GThread.h:175
 GThread.h:176
 GThread.h:177
 GThread.h:178
 GThread.h:179
 GThread.h:180
 GThread.h:181
 GThread.h:182
 GThread.h:183
 GThread.h:184
 GThread.h:185
 GThread.h:186
 GThread.h:187
 GThread.h:188
 GThread.h:189
 GThread.h:190
 GThread.h:191
 GThread.h:192
 GThread.h:193
 GThread.h:194
 GThread.h:195
 GThread.h:196
 GThread.h:197
 GThread.h:198
 GThread.h:199
 GThread.h:200
 GThread.h:201
 GThread.h:202
 GThread.h:203
 GThread.h:204
 GThread.h:205
 GThread.h:206
 GThread.h:207
 GThread.h:208
 GThread.h:209
 GThread.h:210
 GThread.h:211
 GThread.h:212
 GThread.h:213
 GThread.h:214
 GThread.h:215
 GThread.h:216
 GThread.h:217
 GThread.h:218
 GThread.h:219
 GThread.h:220
 GThread.h:221
 GThread.h:222
 GThread.h:223
 GThread.h:224
 GThread.h:225
 GThread.h:226
 GThread.h:227
 GThread.h:228
 GThread.h:229
 GThread.h:230
 GThread.h:231
 GThread.h:232
 GThread.h:233
 GThread.h:234
 GThread.h:235
 GThread.h:236
 GThread.h:237
 GThread.h:238
 GThread.h:239
 GThread.h:240
 GThread.h:241
 GThread.h:242
 GThread.h:243
 GThread.h:244
 GThread.h:245
 GThread.h:246
 GThread.h:247
 GThread.h:248
 GThread.h:249
 GThread.h:250