GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4ThreadManager.cxx
Go to the documentation of this file.
1 // $Id$
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4ThreadManager.h"
15 
16 #include "TSystem.h"
17 #include "TCondition.h"
18 
19 #include "TGo4Log.h"
20 #include "TGo4ThreadHandler.h"
21 #include "TGo4AppControlTimer.h"
22 
23 const Long_t TGo4ThreadManager::fglTIMERPERIOD = 200; // 2000
24 
26  :TNamed(right),
27  fbInitDone(kFALSE),
28  fbTerminating(kFALSE),
29  fbTerminateApplication(kFALSE)
30 {
31  GO4TRACE((15,"TGo4ThreadManager::TGo4ThreadManager copy ctor",__LINE__, __FILE__));
33  fxBlocker = right.fxBlocker;
34 }
35 
36 TGo4ThreadManager::TGo4ThreadManager (const char *name, Bool_t blockingmode, Bool_t autostart, Bool_t autocreate)
37  :TNamed(name,"This is a TGo4ThreadManager"),
38  fbInitDone(kFALSE),
39  fbTerminating(kFALSE),
40  fbTerminateApplication(kFALSE),
41  fbBeingQuit(kFALSE)
42 {
43  GO4TRACE((15,"TGo4ThreadManager::TGo4ThreadManager (const char*, Bool_t, Bool_t, Bool_t) constructor",__LINE__, __FILE__));
44 
45  TString myname=GetName();
46  myname+="-";
47  myname+=gSystem->HostName(); // add hostname
48  myname+="-";
49  myname+=gSystem->GetPid(); // add pid to threadmanager name
50  SetName(myname.Data()); // be unique for multiple client connections!
51  TString nomen("ThreadHandler of "); nomen+=GetName();
52  fxWorkHandler=new TGo4ThreadHandler(nomen.Data(), this);
54  fbAppBlocking=blockingmode;
55  fbAutoCreate=autocreate;
56  fbAutoStart=autostart;
57  if(fbAppBlocking)
58  // manager in blocking mode (analysis without gui)
59  {
60  TGo4Log::Debug(" ThreadManager -- Starting in application blocking mode ");
61  fxBlocker->SetApplicationRun(kFALSE);
62  }
63  else
64  // manager in non blocking mode (for gui)
65  {
66  TGo4Log::Debug(" ThreadManager -- Starting in application non-blocking mode ");
67  fxBlocker->SetApplicationRun(kTRUE);
68  }
69 }
70 
71 
73 {
74  GO4TRACE((15,"TGo4ThreadManager::~TGo4ThreadManager destructor",__LINE__, __FILE__));
75  delete fxWorkHandler; // this will cancel all threads and delete the internal instances
76  //delete fxBlocker; // dtor is called from fxBlocker, may not delete it!
77  //gApplication->Terminate(0);
78 }
79 
81 {
82  GO4TRACE((12,"TGo4ThreadManager::BlockApp()",__LINE__, __FILE__));
83  Bool_t rev=kFALSE;
84  if(fbAppBlocking)
85  {
86  if( !fbTerminating && !( fxWorkHandler->IsOperating() ) )
87  {
88  GO4TRACE((11,"TGo4ThreadManager::BlockApp() blocking mode",__LINE__, __FILE__));
90  rev=kTRUE;
91  }
92  else
93  {
94  // in case of Termination or threadhandler operation:
95  // do not block app again, may deadlock control timer
96  GO4TRACE((11,"TGo4ThreadManager::BlockApp() unblocking mode",__LINE__, __FILE__));
97  rev=kFALSE;
98  }
99  }
100  else
101  {
102  // manager is in non blocking mode (enables gui callback operations)
103  rev=kFALSE;
104  }
105  return rev;
106 }
107 
108 Bool_t TGo4ThreadManager::UnBlockApp (Int_t mode)
109 {
110  GO4TRACE((12,"TGo4ThreadManager::UnBlockApp()",__LINE__, __FILE__));
111  Bool_t rev=kFALSE;
112  switch(mode)
113  {
114  case 0:
115  {
116  GO4TRACE((11,"TGo4ThreadManager::UnBlockApp() mode 0",__LINE__, __FILE__));
118  // only send condition if timer is really waiting
119  {
120 
122  ((TCondition*) fxBlocker->GetCondition() )->Signal();
123  }
124  rev=kTRUE;
125  }
126  break;
127  case 1:
128  {
129  GO4TRACE((11,"TGo4ThreadManager::UnBlockApp() mode 1",__LINE__, __FILE__));
131  rev=kTRUE;
132  }
133  break;
134  case 2:
135  {
136  GO4TRACE((11,"TGo4ThreadManager::UnBlockApp() mode 2",__LINE__, __FILE__));
138  // only send condition if timer is really waiting
139  {
140  ((TCondition*) fxBlocker->GetCondition() )->Signal();
141  }
142  rev=kTRUE;
143  }
144  break;
145  default:
146  {
147  GO4TRACE((16,"++TGo4ThreadManager::UnBlockApp() unknown mode"));
148  //std::cerr << "TGo4ThreadManager::UnBlockApp() unknown mode"<< std::endl;
149  rev=kFALSE;
150  }
151  break;
152  } // switch(mode)
153  return rev;
154 }
155 
157 {
158  GO4TRACE((12,"TGo4ThreadManager::Initialization()",__LINE__, __FILE__));
159  if(fbInitDone)
160  // already initialized, return ok value
161  {
162  GO4TRACE((11,"TGo4ThreadManager::Initialization()--already init done, returning",__LINE__, __FILE__));
163  return 0;
164  }
165  else
166  // first call of initialization: check threads
167  {
168  if(fbAutoCreate)
169  // auto thread creation mode: wait for all threads being up
170  {
171  GO4TRACE((11,"TGo4ThreadManager::Initialization()--in AutoCreate mode",__LINE__, __FILE__));
172  if( fxWorkHandler->AllCreated() )
173  // test for threads, block timer and start work if they are up
174  {
175  TGo4Log::Debug(" ThreadManager -- All threads are up, writing dump file ");
176  BlockApp();
178  if(fbAutoStart)
179  {
180  // autostart mode of runnables
181  GO4TRACE((11,"TGo4ThreadManager::Initialization()--in AutoStart mode",__LINE__, __FILE__));
183  }
184  else
185  {
186  GO4TRACE((11,"TGo4ThreadManager::Initialization()--in non-AutoStart mode",__LINE__, __FILE__));
187 
188  // do not start runnables
189  }
190 
191  fbInitDone=kTRUE;
192  return 0;
193  }
194  else
195  // some threads are missing, suspend starting until next timer cycle
196  {
197  TGo4Log::Debug(" ThreadManager -- some threads are missing, re-doing Init ");
198  return 1;
199  }
200  }
201  else
202  {
203  // do not check or dump threads
204  GO4TRACE((11,"TGo4ThreadManager::Initialization()--not in AutoCreate mode",__LINE__, __FILE__));
205  fbInitDone=kTRUE;
206  return 0;
207  }
208  }
209 }
210 
212 {
213  GO4TRACE((15,"TGo4ThreadManager::Launch()",__LINE__, __FILE__));
214  if(fbAutoCreate)
215  {
216  // create all TThreads of TGo4Threads in threadhandler list
217  GO4TRACE((13,"TGo4ThreadManager::Launch()-- executing AutoCreate mode",__LINE__, __FILE__));
219  }
220  else
221  {
222  // do not create TThreads
223  GO4TRACE((13,"TGo4ThreadManager::Launch()-- no AutoCreate mode",__LINE__, __FILE__));
224  }
225  fxBlocker->TurnOn(); // later in method which is called at the end of derived ctor?
226 }
227 
228 void TGo4ThreadManager::Terminate (Bool_t termapp)
229 {
230  GO4TRACE((15,"TGo4ThreadManager::Terminate()",__LINE__, __FILE__));
231  TGo4Log::Debug(" ThreadManager -- Preparing Termination... ");
233  //gSystem->Sleep(10000); // wait for workfunc to return
234  fbTerminating=kTRUE;
235  fbTerminateApplication=termapp;
236  {
237  GO4TRACE((13,"TGo4ThreadManager::Terminate()--waking up timer:",__LINE__, __FILE__));
238  UnBlockApp(); // wake up blocking timer
239  }
240 }
241 
243 {
244  Terminate();
245 }
246 
virtual Int_t Initialization()
virtual void TerminateFast()
TGo4ThreadHandler * fxWorkHandler
TGo4AppControlTimer * fxBlocker
Bool_t UnBlockApp(Int_t mode=0)
Bool_t GetApplicationRun() const
Int_t DumpThreads(Int_t mode=0)
static void Debug(const char *text,...) GO4_PRINTF_ARGS
Definition: TGo4Log.cxx:281
const TCondition * GetCondition() const
#define GO4TRACE(X)
Definition: TGo4Log.h:25
void SetApplicationRun(Bool_t flag=kTRUE)
Bool_t IsOperating() const
virtual void Terminate(Bool_t termapp=kTRUE)
static const Long_t fglTIMERPERIOD