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