ROOT logo
// $Id: GThread.h 2316 2010-01-01 11:23:28Z 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>
#endif

typedef void*   (*GThread_foo)(void*);
typedef void (*GThread_cu_foo)(void*);

class SaturnInfo;
class ZMirEmittingEntity;
class ZMIR;

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 { SigHUP   =  1, SigINT   =  2, SigQUIT  =  3, SigILL   =  4,
                SigTRAP  =  5, SigABRT  =  6, SigIOT   =  6, SigBUS   =  7,
                SigFPE   =  8, SigKILL  =  9, SigUSR1  = 10, SigSEGV  = 11,
		SigUSR2  = 12, SigPIPE  = 13, SigALRM  = 14, SigTERM  = 15,
                SigSTKFLT= 16, SigCLD   = 17, SigCHLD  = 17, SigCONT  = 18,
                SigSTOP  = 19, SigTSTP  = 20, SigTTIN  = 21, SigTTOU  = 22,
                SigURG   = 23, SigXCPU  = 24, SigXFSZ  = 25, SigVTALRM= 26,
                SigPROF  = 27, SigWINCH = 28, SigPOLL  = 29, SigIO    = 29,
		SigPWR   = 30, SigUNUSED= 31
  }; // from signum.h
  enum RState { RS_Incubating, RS_Spawning,
                RS_Running,
                RS_Terminating, RS_Finished,
                RS_ErrorSpawning
  };

  class CancelDisabler
  {
    CState mExCancelState;
  public:
    CancelDisabler()  { mExCancelState = CancelOff(); }
    ~CancelDisabler() { SetCancelState(mExCancelState); }
  };

private:
  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;

  static GThread      *sMainThread;
  static bool          sMainInitDone;
  static int           sThreadCount;
  static mPThr2GThr_t  sThreadMap;
  static lpGThread_t   sThreadList;
  static GMutex        sContainerLock;
  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*

  // Parameters of thread to be spawned.
  TString        mName;         // X{Gs}
  GThread_foo	 mStartFoo;	// X{gs}
  void*		 mStartArg;	// X{gs}
  GThread_cu_foo mEndFoo;	// X{gs}
  void*		 mEndArg;	// X{gs}
  bool		 bDetached;	// X{g}
  int            mNice;         // X{gs}
  int            mStackSize;    // X{gs}

  // 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 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);
  virtual ~GThread();

  int	Spawn();
  int	Join(void** tret=0);
  int	Kill(Signal signal=SigSTOP);
  int	Cancel();
  int   Detach();

  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 void   TestCancel();
  static void   Exit(void* ret=0);

  static GThread*            Self();
  static ZMirEmittingEntity* Owner();
  static ZMIR*               MIR();

  static const char* RunningStateName(RState state);
  static void        ListThreads();

  static GThread* InitMain();
  static void     FiniMain();

  static int      GetMinStackSize();
  static void     SetMinStackSize(int ss);

#include "GThread.h7"
  ClassDef(GThread, 0);
}; // endclass GThread

#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