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