00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4Thread.h"
00015
00016 #include "Riostream.h"
00017
00018 #include "TThread.h"
00019 #include "TSystem.h"
00020 #include "TCondition.h"
00021
00022 #include "TGo4Runnable.h"
00023 #include "TGo4Log.h"
00024 #include "TGo4LockGuard.h"
00025 #include "Go4Exceptions.h"
00026
00027 TGo4Thread::TGo4Thread(const TGo4Thread &right)
00028 :TNamed(right)
00029 {
00030 TRACE((14,"TGo4Thread::TGo4Thread() copy constructor",__LINE__, __FILE__));
00031 fxRunnable = right.fxRunnable;
00032 fbIsInternal = right.fbIsInternal;
00033 fxCondition = new TCondition();
00034 }
00035
00036 TGo4Thread::TGo4Thread (const char* name, TGo4Runnable* runnable, Bool_t internal)
00037 :TNamed(name,"This is a TGo4Thread"),
00038 fbIsCreated(kFALSE),
00039 fbIsRunning(kFALSE),
00040 fiThreadPID(0),
00041 fiThreadSelfID(0),
00042 fbIsWaiting(kFALSE),
00043 fxThread(0)
00044 {
00045 TRACE((14,"TGo4Thread::TGo4Thread(const char*, TGo4Runnable*, Bool_t) constructor",__LINE__, __FILE__));
00046
00047 TGo4Log::Debug(" New Go4Thread ``%s'' created ",name);
00048 fxRunnable = runnable;
00049 fbIsInternal = internal;
00050 fxCondition = new TCondition();
00051 fxRunnable->SetThread(this);
00052 }
00053
00054
00055 TGo4Thread::~TGo4Thread()
00056 {
00057 TRACE((14,"TGo4Thread::~TGo4Thread() destructor",__LINE__, __FILE__));
00058
00059 Stop();
00060 Cancel();
00061 delete fxCondition;
00062 if(fbIsInternal)
00063 {
00064 TRACE((14,"TGo4Thread::~TGo4Thread() internal mode",__LINE__, __FILE__));
00065 TGo4Log::Debug(" Go4Thread ``%s'' deleting runnable ``%s'' ",
00066 GetName(),fxRunnable->GetName());
00067 delete fxRunnable;
00068 }
00069 else
00070 {
00071 TRACE((14,"TGo4Thread::~TGo4Thread() non internal mode",__LINE__, __FILE__));
00072
00073 }
00074
00075 }
00076
00077 void TGo4Thread::Threadfunc (void* arg)
00078 {
00079 TRACE((2,"TGo4Thread::Threadfunc(void*)",__LINE__, __FILE__));
00080 TGo4Thread* go4th= (TGo4Thread*) arg;
00081 TGo4Runnable* runnable = go4th->GetRunnable();
00082
00083
00084
00085 go4th->SetPID();
00086 go4th->SetSelfID();
00087
00088
00089 TGo4Log::Debug(" TThread %d (PID:%d) of Go4Thread ``%s'' started... \n",
00090 go4th->GetSelfID(), go4th->GetPID(), go4th->GetName());
00091
00092 for(;;)
00093 {
00094 try
00095 {
00096 TRACE((1,"TGo4Thread::Threadfunc(void*) try block",__LINE__, __FILE__));
00097 while(1)
00098 {
00099 TThread::CancelPoint();
00100 if( !(go4th->IsRunning()) )
00101 {
00102 TRACE((1,"TGo4Thread::Threadfunc(void*) waiting mode",__LINE__, __FILE__));
00103 TGo4Log::Debug(" Go4Thread ``%s'' (PID:%d) waiting...\n",
00104 go4th->GetName(), go4th->GetPID());
00105 go4th->SetWaiting(kTRUE);
00106 go4th->GetCondition()->Wait();
00107 go4th->SetWaiting(kFALSE);
00108 TGo4Log::Debug(" Go4Thread ``%s'' (PID:%d) running...\n",
00109 go4th->GetName(), go4th->GetPID() );
00110 }
00111 else
00112 {
00113
00114 }
00115
00116 if(go4th->IsCreated())
00117
00118 {
00119 TRACE((1,"TGo4Thread::Threadfunc(void*) entering running mode",__LINE__, __FILE__));
00120
00121 runnable->PreRun((void*) 0);
00122 while(go4th->IsRunning())
00123 {
00124 TThread::CancelPoint();
00125 runnable->Run((void*) 0);
00126 }
00127
00128 runnable->PostRun((void*) 0);
00129
00130 }
00131 else
00132
00133 {
00134 TRACE((1,"TGo4Thread::Threadfunc(void*) entering Cancel loop",__LINE__, __FILE__));
00135 TGo4Log::Debug(" Go4Thread ``%s'' entering Cancel loop\n ", go4th->GetName());
00136 while(!(go4th->IsCreated()))
00137 {
00138 {
00139 #ifdef WIN32
00140 return;
00141 #endif
00142 TRACE((1,"TGo4Thread::Threadfunc(void*) in Cancel loop",__LINE__, __FILE__));
00143 Sleep(500);
00144 TThread::CancelPoint();
00145 }
00146 }
00147 }
00148 }
00149 }
00150 catch(TGo4Exception& ex)
00151 {
00152 TRACE((1,"TGo4Thread::Threadfunc(void*) Go4Exception Catch",__LINE__, __FILE__));
00153 runnable->ThreadCatch(ex);
00154 TThread::CancelPoint();
00155 }
00156
00157 catch(...)
00158 {
00159 TRACE((1,"TGo4Thread::Threadfunc(void*) Unexpected Catch",__LINE__, __FILE__));
00160
00161 TThread::CancelPoint();
00162 throw;
00163
00164 }
00165
00166 }
00167 }
00168
00169 Bool_t TGo4Thread::Create ()
00170 {
00171 TRACE((14,"TGo4Thread::Create()",__LINE__, __FILE__));
00172 if(!fbIsCreated)
00173
00174 {
00175 fxThread= new TThread(GetName(),
00176 (void(*) (void *)) &Threadfunc ,
00177 (void*) this);
00178 fxThread->Run();
00179 fbIsCreated=kTRUE;
00180 return kTRUE;
00181 }
00182 else
00183
00184 {
00185 return kFALSE;
00186 }
00187 }
00188
00189 Bool_t TGo4Thread::Cancel ()
00190 {
00191 TRACE((14,"TGo4Thread::Cancel()",__LINE__, __FILE__));
00192
00193 if(fbIsCreated)
00194
00195 {
00196 TGo4Log::Debug(" Go4Thread ``%s'' -- Canceling TThread %d (PID:%d) ",
00197 GetName(), fiThreadSelfID, fiThreadPID);
00198
00199 if(fxThread)
00200 {
00201 TRACE((13,"TGo4Thread::Cancel() -- canceling existing TThread",__LINE__, __FILE__));
00202 fbIsCreated=kFALSE;
00203 fbIsRunning=kTRUE;
00204 fxCondition->Signal();
00205 Sleep(500);
00206
00207
00208
00209
00210
00211
00212
00213 fxThread->Kill();
00214 delete fxThread;
00215
00216
00218
00219
00220
00221
00222
00223
00224
00225
00226 fxThread=0;
00227 fiThreadPID=0;
00228 fiThreadSelfID=0;
00229
00230 }
00231 else
00232 {
00233 TRACE((13,"TGo4Thread::Cancel() -- Error: TThread pointer is zero!",__LINE__, __FILE__));
00234 TGo4Log::Debug(" Go4Thread ``%s'' Cancel -- Internal inconsistency error! ",GetName());
00235 throw TGo4RuntimeException();
00236 }
00237 return kTRUE;
00238 }
00239 else
00240
00241 {
00242 return kFALSE;
00243 }
00244 }
00245
00246 Bool_t TGo4Thread::ReCreate ()
00247 {
00248 TRACE((14,"TGo4Thread::ReCreate()",__LINE__, __FILE__));
00249
00250 TThread* oldthread;
00251 if(fbIsCreated)
00252
00253
00254 {
00255 TRACE((13,"TGo4Thread::ReCreate() -- old TThread existing",__LINE__, __FILE__));
00256 TGo4Log::Debug(" Recreating Go4Thread ``%s'' -- old TThread %d (PID:%d) ",
00257 GetName(), fiThreadSelfID, fiThreadPID);
00258
00259 if(fxThread)
00260 {
00261 TRACE((13,"TGo4Thread::ReCreate() -- recreating existing TThread",__LINE__, __FILE__));
00262 Stop();
00263 oldthread=fxThread;
00264
00265 fxThread= new TThread(GetName(),
00266 (void(*) (void *)) &Threadfunc ,
00267 (void*) this);
00268
00269
00270 fbIsCreated=kFALSE;
00271 if(fbIsWaiting)
00272 {
00273 fxCondition->Signal();
00274
00275
00276 }
00277 TThread::Delete(oldthread);
00278
00279 fbIsCreated=kTRUE;
00280 fxThread->Run();
00281 Start();
00282
00283 }
00284 else
00285 {
00286 TRACE((13,"TGo4Thread::ReCreate() -- Error: old TThread pointer is zero!",__LINE__, __FILE__));
00287 TGo4Log::Debug(" Go4Thread ``%s'' ReCreate -- Internal inconsistency error! ",GetName());
00288
00289 throw TGo4RuntimeException();
00290 }
00291 return kTRUE;
00292 }
00293 else
00294
00295 {
00296 TRACE((13,"TGo4Thread::ReCreate() -- old TThread existing",__LINE__, __FILE__));
00297 Create();
00298 return kFALSE;
00299 }
00300 }
00301
00302 Bool_t TGo4Thread::Start ()
00303 {
00304 TRACE((12,"TGo4Thread::Start()",__LINE__, __FILE__));
00305 if(!fbIsCreated)
00306
00307 {
00308
00309 TRACE((11,"TGo4Thread::Start() -- creating new TThread",__LINE__, __FILE__));
00310 Create();
00311 }
00312 else
00313 {
00314
00315 TRACE((11,"TGo4Thread::Start() -- TThread already existing",__LINE__, __FILE__));
00316 }
00317 Bool_t old=fbIsRunning;
00318 fbIsRunning=kTRUE;
00319 fxCondition->Signal();
00320 return old;
00321 }
00322
00323 Bool_t TGo4Thread::Stop ()
00324 {
00325 TRACE((12,"TGo4Thread::Stop()",__LINE__, __FILE__));
00326 Bool_t old=fbIsRunning;
00327 fbIsRunning=kFALSE;
00328 return old;
00329 }
00330
00331 void TGo4Thread::Sleep (UInt_t millisecs)
00332 {
00333 TRACE((12,"TGo4Thread::Sleep()",__LINE__, __FILE__));
00334 gSystem->Sleep(millisecs);
00335 TThread::CancelPoint();
00336 }
00337
00338 void TGo4Thread::SetSelfID()
00339 {
00340 fiThreadSelfID = TThread::SelfId();
00341 }
00342
00343 void TGo4Thread::SetPID()
00344 {
00345 fiThreadPID = gSystem->GetPid();
00346 }