00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4ThreadHandler.h"
00015
00016 #include "TGo4Thread.h"
00017 #include "TIterator.h"
00018 #include "TObjArray.h"
00019 #include "TMutex.h"
00020
00021 #include "TGo4Log.h"
00022 #include "TGo4LockGuard.h"
00023 #include "TGo4ThreadManager.h"
00024
00025 TGo4ThreadHandler::TGo4ThreadHandler(const TGo4ThreadHandler &right)
00026 : TNamed(right)
00027 {
00028 GO4TRACE((15,"TGo4ThreadHandler::TGo4ThreadHandler() copy constructor",__LINE__, __FILE__));
00029 fxManager = right.fxManager;
00030 fxListMutex=new TMutex;
00031 fxOperMutex=new TMutex;
00032 fxArray= (TObjArray*) ((right.fxArray)->Clone());
00033 fxIterator=fxArray->MakeIterator();
00034 }
00035
00036 TGo4ThreadHandler::TGo4ThreadHandler (const char* name, TGo4ThreadManager* parent)
00037 :TNamed(name,"This is a TGo4ThreadHandler"),fbIsOperating(kFALSE)
00038 {
00039 GO4TRACE((15,"TGo4ThreadHandler::TGo4ThreadHandler(const char*, TGo4ThreadManager*) constructor",__LINE__, __FILE__));
00040 fxManager=parent;
00041 fxListMutex=new TMutex;
00042 fxOperMutex=new TMutex;
00043 fxArray=new TObjArray;
00044 fxIterator=fxArray->MakeIterator();
00045 }
00046
00047
00048 TGo4ThreadHandler::~TGo4ThreadHandler()
00049 {
00050 GO4TRACE((15,"TGo4ThreadHandler::~TGo4ThreadHandler() destructor",__LINE__, __FILE__));
00051 StopAll();
00052 CancelAll();
00053 TGo4Thread* th=0;
00054 {
00055 TGo4LockGuard listguard(fxListMutex);
00056 fxIterator->Reset();
00057 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00058 {
00059 if(th->IsInternal())
00060
00061 {
00062 GO4TRACE((14,"TGo4ThreadHandler::~TGo4ThreadHandler() Removing internal mode thread",__LINE__, __FILE__));
00063 fxArray->Remove(th);
00064 fxArray->Compress();
00065 fxArray->Expand(fxArray->GetLast()+1);
00066 delete th;
00067 }
00068 else
00069 {
00070
00071 GO4TRACE((14,"TGo4ThreadHandler::~TGo4ThreadHandler() Non internal mode thread",__LINE__, __FILE__));
00072 }
00073 }
00074 delete fxIterator;
00075 fxArray->Clear();
00076 delete fxArray;
00077 }
00078 delete fxListMutex;
00079 delete fxOperMutex;
00080 }
00081
00082
00083 Bool_t TGo4ThreadHandler::AddThread (TGo4Thread* gthr)
00084 {
00085 GO4TRACE((14,"TGo4ThreadHandler::AddThread(TGo4Thread*)",__LINE__, __FILE__));
00086 Bool_t rev=kFALSE;
00087 {
00088 TGo4LockGuard listguard(fxListMutex);
00089 if(fxArray->FindObject(gthr)==0)
00090
00091 {
00092
00093 GO4TRACE((13,"TGo4ThreadHandler::AddThread(TGo4Thread*) Adding new go4 thread to array",__LINE__, __FILE__));
00094 fxArray->AddLast(gthr);
00095 rev=kTRUE;
00096 }
00097 else
00098 {
00099
00100 GO4TRACE((13,"TGo4ThreadHandler::AddThread(TGo4Thread*) Thread was already in array",__LINE__, __FILE__));
00101 rev=kFALSE;
00102 }
00103 }
00104 return rev;
00105 }
00106
00107 Bool_t TGo4ThreadHandler::RemoveThread (const char* name)
00108 {
00109 GO4TRACE((14,"TGo4ThreadHandler::RemoveThread(const char*)",__LINE__, __FILE__));
00110 Bool_t rev=kFALSE;
00111 {
00112 TGo4LockGuard listguard(fxListMutex);
00113 TObject* obj=fxArray->FindObject(name);
00114 TGo4Thread* th= (TGo4Thread*) obj;
00115 if(obj!=0)
00116
00117 {
00118 GO4TRACE((13,"TGo4ThreadHandler::RemoveThread(const char*) Removing thread from array",__LINE__, __FILE__));
00119 fxArray->Remove(obj);
00120 fxArray->Compress();
00121 fxArray->Expand(fxArray->GetLast()+1);
00122 if(th->IsInternal())
00123
00124 {
00125 GO4TRACE((13,"TGo4ThreadHandler::RemoveThread(const char*) Deleting internal mode thread",__LINE__, __FILE__));
00126 TGo4LockGuard operguard(fxOperMutex);
00127 fbIsOperating=kTRUE;
00128 fxManager->UnBlockApp();
00129 delete th;
00130 fbIsOperating=kFALSE;
00131 fxManager->BlockApp();
00132 }
00133 else
00134 {
00135
00136 GO4TRACE((13,"TGo4ThreadHandler::RemoveThread(const char*) Non internal mode thread is not deleted",__LINE__, __FILE__));
00137 }
00138 rev=kTRUE;
00139 }
00140 else
00141 {
00142 GO4TRACE((13,"TGo4ThreadHandler::RemoveThread(const char*) Thread not found in array",__LINE__, __FILE__));
00143 rev=kFALSE;
00144 }
00145 }
00146 return rev;
00147 }
00148
00149 Bool_t TGo4ThreadHandler::NewThread(const char* name, TGo4Runnable* runnable)
00150 {
00151 GO4TRACE((14,"TGo4ThreadHandler::NewThread(const char*,TGo4Runnable*)",__LINE__, __FILE__));
00152 TGo4Runnable* nrun=0;
00153 TGo4Thread* nthread=0;
00154 if(runnable==0)
00155 {
00156 GO4TRACE((13,"TGo4ThreadHandler::NewThread(const char*,TGo4Runnable*) No runnable specified error",__LINE__, __FILE__));
00157 return kFALSE;
00158
00159 }
00160 else
00161 {
00162 GO4TRACE((13,"TGo4ThreadHandler::NewThread(const char*,TGo4Runnable*) Assigning external runnable to new internal thread",__LINE__, __FILE__));
00163 nrun=runnable;
00164 }
00165 nthread= new TGo4Thread(name,nrun,kTRUE);
00166 return AddThread(nthread);
00167 }
00168
00169 Int_t TGo4ThreadHandler::CreateAll ()
00170 {
00171 GO4TRACE((15,"TGo4ThreadHandler::CreateAll()",__LINE__, __FILE__));
00172 Int_t createdthreads=0;
00173 TGo4Thread* th=0;
00174 {
00175 TGo4LockGuard listguard(fxListMutex);
00176 TGo4LockGuard operguard(fxOperMutex);
00177 fbIsOperating=kTRUE;
00178 fxManager->UnBlockApp();
00179 fxIterator->Reset();
00180 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00181 {
00182 if(th->Create())
00183 {
00184 GO4TRACE((13,"TGo4ThreadHandler::CreateAll() Thread creation success",__LINE__, __FILE__));
00185 ++createdthreads;
00186 }
00187 else
00188 {
00189 GO4TRACE((13,"TGo4ThreadHandler::CreateAll() Thread not created",__LINE__, __FILE__));
00190
00191 }
00192 }
00193 fxManager->BlockApp();
00194 fbIsOperating=kFALSE;
00195 }
00196 return createdthreads;
00197 }
00198
00199 Bool_t TGo4ThreadHandler::Create (const char* thname)
00200 {
00201 GO4TRACE((14,"TGo4ThreadHandler::Create(const char*)",__LINE__, __FILE__));
00202 Bool_t rev=kFALSE;
00203 TGo4Thread* th=GetThread(thname);
00204 if(th!=0)
00205
00206 {
00207 GO4TRACE((13,"TGo4ThreadHandler::Create(const char*) Creating new TThread for Go4Thread",__LINE__, __FILE__));
00208 TGo4LockGuard operguard(fxOperMutex);
00209 fbIsOperating=kTRUE;
00210 fxManager->UnBlockApp();
00211 rev=th->Create();
00212 fbIsOperating=kFALSE;
00213 fxManager->BlockApp();
00214 }
00215 else
00216
00217 {
00218 GO4TRACE((13,"TGo4ThreadHandler::Create(const char*) Go4Thread was not found in thread array!",__LINE__, __FILE__));
00219 rev=kFALSE;
00220 }
00221 return rev;
00222 }
00223
00224 Int_t TGo4ThreadHandler::CancelAll ()
00225 {
00226 GO4TRACE((15,"TGo4ThreadHandler::CancelAll()",__LINE__, __FILE__));
00227 Int_t cancelledthreads=0;
00228 TGo4Thread* th=0;
00229 {
00230 TGo4LockGuard listguard(fxListMutex);
00231 TGo4LockGuard operguard(fxOperMutex);
00232 fbIsOperating=kTRUE;
00233 fxIterator->Reset();
00234 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00235 {
00236 if(th->Cancel())
00237 {
00238 GO4TRACE((13,"TGo4ThreadHandler::CancelAll() Thread Cancel success",__LINE__, __FILE__));
00239 ++cancelledthreads;
00240 }
00241 else
00242 {
00243
00244 GO4TRACE((13,"TGo4ThreadHandler::CancelAll() Thread was not canceled",__LINE__, __FILE__));
00245
00246 }
00247 }
00248 fbIsOperating=kFALSE;
00249 }
00250 return cancelledthreads;
00251 }
00252
00253 Bool_t TGo4ThreadHandler::Cancel (const char* thname)
00254 {
00255 GO4TRACE((14,"TGo4ThreadHandler::Cancel(const char*)",__LINE__, __FILE__));
00256 Bool_t rev=kFALSE;
00257 TGo4Thread* th=GetThread(thname);
00258 if(th!=0)
00259
00260 {
00261 GO4TRACE((13,"TGo4ThreadHandler::Cancel(const char*) Canceling TThread",__LINE__, __FILE__));
00262 TGo4LockGuard operguard(fxOperMutex);
00263 fbIsOperating=kTRUE;
00264 fxManager->UnBlockApp();
00265 rev=th->Cancel();
00266 fbIsOperating=kFALSE;
00267 fxManager->BlockApp();
00268 }
00269 else
00270
00271 {
00272 GO4TRACE((13,"TGo4ThreadHandler::Cancel(const char*) Go4Thread was not found in thread array!",__LINE__, __FILE__));
00273 rev=kFALSE;
00274 }
00275 return rev;
00276 }
00277
00278 Int_t TGo4ThreadHandler::ReCreateAll ()
00279 {
00280 GO4TRACE((15,"TGo4ThreadHandler::ReCreateAll()",__LINE__, __FILE__));
00281 Int_t recreatedthreads=0;
00282 TGo4Thread* th=0;
00283 {
00284 TGo4LockGuard listguard(fxListMutex);
00285 TGo4LockGuard operguard(fxOperMutex);
00286 fbIsOperating=kTRUE;
00287 fxIterator->Reset();
00288 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00289 {
00290 if(th->ReCreate())
00291 {
00292 GO4TRACE((13,"TGo4ThreadHandler::ReCreateAll() Thread ReCreate success",__LINE__, __FILE__));
00293 ++recreatedthreads;
00294 }
00295 else
00296 {
00297
00298 GO4TRACE((13,"TGo4ThreadHandler::ReCreateAll() Thread was not recreated",__LINE__, __FILE__));
00299
00300 }
00301 }
00302 fbIsOperating=kFALSE;
00303 }
00304 return recreatedthreads;
00305 }
00306
00307 Bool_t TGo4ThreadHandler::ReCreate (const char* thname)
00308 {
00309 GO4TRACE((14,"TGo4ThreadHandler::ReCreate(const char*)",__LINE__, __FILE__));
00310 Bool_t rev=kFALSE;
00311 TGo4Thread* th=GetThread(thname);
00312 if(th!=0)
00313
00314 {
00315 GO4TRACE((13,"TGo4ThreadHandler::ReCreate(const char*) ReCreating TThread for Go4Thread",__LINE__, __FILE__));
00316 TGo4LockGuard operguard(fxOperMutex);
00317 fbIsOperating=kTRUE;
00318 fxManager->UnBlockApp();
00319 rev=th->ReCreate();
00320 fbIsOperating=kFALSE;
00321 fxManager->BlockApp();
00322 }
00323 else
00324
00325 {
00326 GO4TRACE((13,"TGo4ThreadHandler::ReCreate(const char*) Go4Thread was not found in thread array!",__LINE__, __FILE__));
00327 rev=kFALSE;
00328 }
00329
00330 return rev;
00331 }
00332
00333 Int_t TGo4ThreadHandler::StartAll ()
00334 {
00335 GO4TRACE((15,"TGo4ThreadHandler::StartAll()",__LINE__, __FILE__));
00336 Int_t startedfuncs=0;
00337 TGo4Thread* th=0;
00338 {
00339 TGo4LockGuard listguard(fxListMutex);
00340 TGo4LockGuard operguard(fxOperMutex);
00341 fbIsOperating=kTRUE;
00342 fxManager->UnBlockApp();
00343 fxIterator->Reset();
00344 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00345 {
00346 if(!th->Start())
00347
00348
00349 {
00350
00351 GO4TRACE((13,"TGo4ThreadHandler::StartAll() Thread Start success",__LINE__, __FILE__));
00352 ++startedfuncs;
00353 }
00354 else
00355 {
00356
00357
00358 GO4TRACE((13,"TGo4ThreadHandler::StartAll() Thread was already running",__LINE__, __FILE__));
00359 }
00360 }
00361 fbIsOperating=kFALSE;
00362 fxManager->BlockApp();
00363 }
00364 return startedfuncs;
00365 }
00366
00367 Bool_t TGo4ThreadHandler::Start (const char* thname)
00368 {
00369 GO4TRACE((14,"TGo4ThreadHandler::Start(const char*)",__LINE__, __FILE__));
00370 Bool_t rev=kFALSE;
00371 TGo4Thread* th=GetThread(thname);
00372 if(th!=0)
00373
00374 {
00375 GO4TRACE((13,"TGo4ThreadHandler::Start(const char*) Starting Thread",__LINE__, __FILE__));
00376 TGo4LockGuard operguard(fxOperMutex);
00377 fbIsOperating=kTRUE;
00378 fxManager->UnBlockApp();
00379 rev=th->Start();
00380 fbIsOperating=kFALSE;
00381 fxManager->BlockApp();
00382 }
00383 else
00384
00385 {
00386 GO4TRACE((13,"TGo4ThreadHandler::Start(const char*) Go4Thread was not found in thread array!",__LINE__, __FILE__));
00387 rev=kFALSE;
00388 }
00389 return rev;
00390 }
00391
00392 Int_t TGo4ThreadHandler::StopAll ()
00393 {
00394 GO4TRACE((15,"TGo4ThreadHandler::StopAll()",__LINE__, __FILE__));
00395 Int_t stoppedfuncs=0;
00396 TGo4Thread* th=0;
00397 {
00398 TGo4LockGuard listguard(fxListMutex);
00399 fxIterator->Reset();
00400 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00401 {
00402 if(th->Stop())
00403
00404 {
00405
00406 GO4TRACE((13,"TGo4ThreadHandler::StopAll() Go4Thread Stop success",__LINE__, __FILE__));
00407 ++stoppedfuncs;
00408 }
00409 else
00410 {
00411
00412
00413 GO4TRACE((13,"TGo4ThreadHandler::StopAll() Go4Thread was already stopped",__LINE__, __FILE__));
00414 }
00415 }
00416 }
00417 return stoppedfuncs;
00418 }
00419
00420 Bool_t TGo4ThreadHandler::Stop (const char* thname)
00421 {
00422 GO4TRACE((14,"TGo4ThreadHandler::Stop(const char*)",__LINE__, __FILE__));
00423 Bool_t rev=kFALSE;
00424 TGo4Thread* th=GetThread(thname);
00425 if(th!=0)
00426
00427 {
00428 GO4TRACE((13,"TGo4ThreadHandler::Stop(const char*) Stopping Go4Runnable",__LINE__, __FILE__));
00429 rev=th->Stop();
00430 }
00431 else
00432
00433 {
00434 GO4TRACE((13,"TGo4ThreadHandler::Stop(const char*) Go4Thread was not found in thread array!",__LINE__, __FILE__));
00435 rev=kFALSE;
00436 }
00437 return rev;
00438 }
00439
00440 Int_t TGo4ThreadHandler::DumpThreads (Int_t mode)
00441 {
00442 GO4TRACE((15,"TGo4ThreadHandler::DumpThreads(Int_t)",__LINE__, __FILE__));
00443 if(TGo4Log::GetIgnoreLevel()>0) return 2;
00444 Int_t retval=0;
00445 TGo4Thread* th=0;
00446 FILE* fp;
00447 Int_t i=0;
00448 char Filename[80];
00449 switch(mode)
00450 {
00451 case 0:
00452 {
00453 GO4TRACE((14,"TGo4ThreadHandler::DumpThreads(Int_t) mode 0: File output",__LINE__, __FILE__));
00454 strcpy(Filename,"threaddump.txt");
00455 fp = fopen(Filename,"w");
00456 if (!fp)
00457 {
00458 GO4TRACE((13,"TGo4ThreadHandler::DumpThreads(Int_t) fopen failed!!",__LINE__, __FILE__));
00459 TGo4Log::Debug(" ThreadHandler -- Error, Could not open thread dump file!");
00460 retval=1;
00461 break;
00462 }
00463 else
00464 {
00465 GO4TRACE((13,"TGo4ThreadHandler::DumpThreads(Int_t) writing into opened file",__LINE__, __FILE__));
00466 fprintf(fp,"\nTGo4ThreadHandler thread information dump file:\n");
00467 {
00468 TGo4LockGuard listguard(fxListMutex);
00469 fxIterator->Reset();
00470 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00471 {
00472 fprintf(fp,"TGo4Thread %d: \tPID:%d \tSelfID: %d",
00473 i++,th->GetPID(),(int) th->GetSelfID());
00474 fprintf(fp,"\t name: %s\n",th->GetName());
00475 }
00476 }
00477 if (fclose(fp))
00478 {
00479 GO4TRACE((13,"TGo4ThreadHandler::DumpThreads(Int_t) fclose failed!!",__LINE__, __FILE__));
00480 TGo4Log::Debug(" ThreadHandlerr -- Error, Could not close thread dump file!");
00481 retval=1;
00482 }
00483 }
00484 }
00485 break;
00486 default:
00487 {
00488 GO4TRACE((14,"TGo4ThreadHandler::DumpThreads(Int_t) mode: default ",__LINE__, __FILE__));
00489 TGo4Log::Debug(" ThreadHandlerr -- Error: DumpThreads mode unknown ");
00490 }
00491 break;
00492 }
00493 return retval;
00494 }
00495
00496 TGo4Thread* TGo4ThreadHandler::GetThread (const char* name)
00497 {
00498 GO4TRACE((12,"TGo4ThreadHandler::GetThread(const char*)",__LINE__, __FILE__));
00499 TGo4Thread* thread=0;
00500 {
00501 TGo4LockGuard listguard(fxListMutex);
00502 thread = (TGo4Thread*) fxArray->FindObject(name);
00503 }
00504 return thread;
00505 }
00506
00507 Int_t TGo4ThreadHandler::GetEntries ()
00508 {
00509 GO4TRACE((12,"TGo4ThreadHandler::GetEntries()",__LINE__, __FILE__));
00510 Int_t entries=0;
00511 {
00512 TGo4LockGuard listguard(fxListMutex);
00513 entries=fxArray->GetEntries();
00514 }
00515 return entries;
00516 }
00517
00518 Bool_t TGo4ThreadHandler::AllCreated ()
00519 {
00520 GO4TRACE((14,"TGo4ThreadHandler::AllCreated()",__LINE__, __FILE__));
00521 Bool_t rev=kTRUE;
00522 TGo4Thread* th=0;
00523 {
00524 TGo4LockGuard listguard(fxListMutex);
00525 fxIterator->Reset();
00526 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00527 {
00528 if((th->GetPID())==0)
00529 {
00530 GO4TRACE((11,"TGo4ThreadHandler::AllCreated() TThread is _not_ existing",__LINE__, __FILE__));
00531 rev=kFALSE;
00532 break;
00533 }
00534 else
00535 {
00536 GO4TRACE((11,"TGo4ThreadHandler::AllCreated() TThread is existing",__LINE__, __FILE__));
00537
00538 }
00539 }
00540 }
00541 return rev;
00542 }
00543
00544 Bool_t TGo4ThreadHandler::AllRunning ()
00545 {
00546 GO4TRACE((14,"TGo4ThreadHandler::AllRunning()",__LINE__, __FILE__));
00547 Bool_t rev=kTRUE;
00548 TGo4Thread* th=0;
00549 {
00550 TGo4LockGuard listguard(fxListMutex);
00551 fxIterator->Reset();
00552 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00553 {
00554 if(!(th->IsRunning()))
00555 {
00556 GO4TRACE((11,"TGo4ThreadHandler::AllCreated() TGo4Thread is _not_ running",__LINE__, __FILE__));
00557 rev=kFALSE;
00558 break;
00559 }
00560 else
00561 {
00562 GO4TRACE((11,"TGo4ThreadHandler::AllCreated() TGo4Thread is running",__LINE__, __FILE__));
00563
00564 }
00565 }
00566 }
00567 return rev;
00568 }
00569
00570 Bool_t TGo4ThreadHandler::AllWaiting ()
00571 {
00572 GO4TRACE((14,"TGo4ThreadHandler::AllWaiting()",__LINE__, __FILE__));
00573 Bool_t rev=kTRUE;
00574 TGo4Thread* th=0;
00575 {
00576 TGo4LockGuard listguard(fxListMutex);
00577 fxIterator->Reset();
00578 while((th= (TGo4Thread*) fxIterator->Next())!=0)
00579 {
00580 if(!(th->IsWaiting()))
00581 {
00582 GO4TRACE((11,"TGo4ThreadHandler::AllCreated() TGo4Thread is still running",__LINE__, __FILE__));
00583
00584 rev=kFALSE;
00585 break;
00586 }
00587 else
00588 {
00589 GO4TRACE((11,"TGo4ThreadHandler::AllCreated() TGo4Thread is waiting",__LINE__, __FILE__));
00590
00591 }
00592 }
00593 }
00594 return rev;
00595 }