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