// @(#)root/thread:$Id$
// Author: Fons Rademakers   02/07/97

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TThread
#define ROOT_TThread


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TThread                                                              //
//                                                                      //
// This class implements threads. A thread is an execution environment  //
// much lighter than a process. A single process can have multiple      //
// threads. The actual work is done via the TThreadImp class (either    //
// TPosixThread or TWin32Thread).                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TMutex
#include "TMutex.h"
#endif
#ifndef ROOT_TCondition
#include "TCondition.h"
#endif
#ifndef ROOT_TSystem
#include "TSystem.h"
#endif
#ifndef ROOT_TTimer
#include "TTimer.h"
#endif
#ifndef ROOT_Varargs
#include "Varargs.h"
#endif
#ifndef ROOT_TThreadSlots
#include "TThreadSlots.h"
#endif

class TThreadImp;


class TThread : public TNamed {

friend class TThreadImp;
friend class TPosixThread;
friend class TThreadTimer;
friend class TThreadCleaner;
friend class TWin32Thread;

public:

   typedef void *(*VoidRtnFunc_t)(void *);
   typedef void  (*VoidFunc_t)(void *);

   enum EPriority {
      kLowPriority,
      kNormalPriority,
      kHighPriority
   };

   enum EState {
      kInvalidState,            // thread was not created properly
      kNewState,                // thread object exists but hasn't started
      kRunningState,            // thread is running
      kTerminatedState,         // thread has terminated but storage has not
                                // yet been reclaimed (i.e. waiting to be joined)
      kFinishedState,           // thread has finished
      kCancelingState,          // thread in process of canceling
      kCanceledState,           // thread has been canceled
      kDeletingState            // thread in process of deleting
   };

private:
   TThread       *fNext;                  // pointer to next thread
   TThread       *fPrev;                  // pointer to prev thread
   TThread      **fHolder;                // pointer to holder of this (delete only)
   EPriority      fPriority;              // thread priority
   EState         fState;                 // thread state
   EState         fStateComing;           // coming thread state
   Long_t         fId;                    // thread id
   Long_t         fHandle;                // Win32 thread handle
   Bool_t         fDetached;              // kTRUE if thread is Detached
   Bool_t         fNamed;                 // kTRUE if thread is Named
   VoidRtnFunc_t  fFcnRetn;               // void* start function of thread
   VoidFunc_t     fFcnVoid;               // void  start function of thread
   void          *fThreadArg;             // thread start function arguments
   void          *fClean;                 // support of cleanup structure
   void          *fTsd[ROOT::kMaxThreadSlot]; // thread specific data container
   char           fComment[100];          // thread specific state comment

   static TThreadImp      *fgThreadImp;   // static pointer to thread implementation
   static char  * volatile fgXAct;        // Action name to do by main thread
   static void ** volatile fgXArr;        // pointer to control array of void pointers for action
   static volatile Int_t   fgXAnb;        // size of array above
   static volatile Int_t   fgXArt;        // return XA flag
   static Long_t           fgMainId;      // thread id of main thread
   static TThread         *fgMain;        // pointer to chain of TThread's
   static TMutex          *fgMainMutex;   // mutex to protect chain of threads
   static TMutex          *fgXActMutex;   // mutex to protect XAction
   static TCondition      *fgXActCondi;   // condition for XAction

   // Private Member functions
   void           Constructor();
   void           SetComment(const char *txt = 0)
                     { fComment[0] = 0; if (txt) { strncpy(fComment, txt, 99); fComment[99] = 0; } }
   void           DoError(Int_t level, const char *location, const char *fmt, va_list va) const;
   void           ErrorHandler(int level, const char *location, const char *fmt, va_list ap) const;
   static void    Init();
   static void   *Function(void *ptr);
   static Int_t   XARequest(const char *xact, Int_t nb, void **ar, Int_t *iret);
   static void    AfterCancel(TThread *th);

   TThread(const TThread&);            // not implemented
   TThread& operator=(const TThread&); // not implemented

public:
   TThread(VoidRtnFunc_t fn, void *arg = 0, EPriority pri = kNormalPriority);
   TThread(VoidFunc_t fn, void *arg = 0, EPriority pri = kNormalPriority);
   TThread(const char *thname, VoidRtnFunc_t fn, void *arg = 0, EPriority pri = kNormalPriority);
   TThread(const char *thname, VoidFunc_t fn, void *arg = 0, EPriority pri = kNormalPriority);
   TThread(Long_t id = 0);
   virtual ~TThread();

   Int_t            Kill();
   Int_t            Run(void *arg = 0);
   void             SetPriority(EPriority pri);
   void             Delete(Option_t *option="") { TObject::Delete(option); }
   EPriority        GetPriority() const { return fPriority; }
   EState           GetState() const { return fState; }
   Long_t           GetId() const { return fId; }
   static void      Ps();
   static void      ps() { Ps(); }

   static void      Initialize();
   static Bool_t    IsInitialized();

   Long_t           Join(void **ret = 0);
   static Long_t    Join(Long_t id, void **ret = 0);

   static Int_t     Exit(void *ret = 0);
   static Int_t     Exists();
   static TThread  *GetThread(Long_t id);
   static TThread  *GetThread(const char *name);

   static Int_t     Lock();                  //User's lock of main mutex
   static Int_t     TryLock();               //User's try lock of main mutex
   static Int_t     UnLock();                //User's unlock of main mutex
   static TThread  *Self();
   static Long_t    SelfId();
   static Int_t     Sleep(ULong_t secs, ULong_t nanos = 0);
   static Int_t     GetTime(ULong_t *absSec, ULong_t *absNanoSec);

   static Int_t     Delete(TThread *&th);
   static void    **Tsd(void *dflt, Int_t k);

   // Cancellation
   // there are two types of TThread cancellation:
   //    DEFERRED     - Cancellation only in user provided cancel-points
   //    ASYNCHRONOUS - In any point
   //    DEFERRED is more safe, it is DEFAULT.
   static Int_t     SetCancelOn();
   static Int_t     SetCancelOff();
   static Int_t     SetCancelAsynchronous();
   static Int_t     SetCancelDeferred();
   static Int_t     CancelPoint();
   static Int_t     Kill(Long_t id);
   static Int_t     Kill(const char *name);
   static Int_t     CleanUpPush(void *free, void *arg = 0);
   static Int_t     CleanUpPop(Int_t exe = 0);
   static Int_t     CleanUp();

   // XActions
   static void      Printf(const char *fmt, ...)   // format and print
#if defined(__GNUC__) && !defined(__CINT__)
   __attribute__((format(printf, 1, 2)))
#endif
   ;
   static void      XAction();

   ClassDef(TThread,0)  // Thread class
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TThreadCleaner                                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TThreadCleaner {
public:
   TThreadCleaner() { }
   ~TThreadCleaner();
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TThreadTimer                                                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TThreadTimer : public TTimer {
public:
   TThreadTimer(Long_t ms = 10);
   Bool_t Notify();
};

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