CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TRootXTReq.cc
Go to the documentation of this file.
1 // $Id: TRootXTReq.cc,v 1.3 2011/01/24 17:44:21 amraktad Exp $
2 
4 
5 #include "TCondition.h"
6 #include "TThread.h"
7 
8 #include <TSysEvtHandler.h>
9 #include <TSystem.h>
10 #include <TTimer.h>
11 
12 // Bloody root threads do not provide signal delivery.
13 #include <csignal>
14 
15 // TRootXTReq
16 
17 //______________________________________________________________________________
18 //
19 // Abstract base-class for delivering cross-thread requests into ROOT
20 // main thread.
21 // Sub-classes must implement the Act() method.
22 // Two methods are available to request execution:
23 //
24 // - ShootRequest()
25 // Request execution and return immediately.
26 // The request object is deleted in the main thread.
27 //
28 // - ShootRequestAndWait()
29 // Request execution and wait until execution is finished.
30 // This way results can be returned to the caller in data-members.
31 // It is callers responsibility to delete the request object.
32 // It can also be reused.
33 //
34 //
35 // Global queue and locks are implemented via static members of this
36 // class.
37 //
38 // Must be initialized from the main thread like this:
39 // TRootXTReq::Bootstrap(TThread::SelfId());
40 
41 
43 pthread_t TRootXTReq::sRootThread = 0;
44 TMutex *TRootXTReq::sQueueMutex = 0;
45 TSignalHandler *TRootXTReq::sSigHandler = 0;
46 bool TRootXTReq::sSheduled = false;
47 
48 
49 //==============================================================================
50 
51 TRootXTReq::TRootXTReq(const char* n) :
52  m_return_condition(0),
53  mName(n)
54 {}
55 
57 {
58  delete m_return_condition;
59 }
60 
61 //------------------------------------------------------------------------------
62 
64 {
65  TLockGuard _lck(sQueueMutex);
66 
67  sQueue.push_back(this);
68 
69  if ( ! sSheduled)
70  {
71  sSheduled = true;
72  pthread_kill(sRootThread, SIGUSR1);
73  }
74 }
75 
77 {
78  // Places request into the queue and requests execution in Rint thread.
79  // It returns immediately after that, without waiting for execution.
80  // The request is deleted after execution.
81 
83  {
84  delete m_return_condition;
86  }
87 
88  post_request();
89 }
90 
92 {
93  // Places request into the queue, requests execution in Rint thread and
94  // waits for the execution to be completed.
95  // The request is not deleted after execution as it might carry return
96  // value.
97  // The same request can be reused several times.
98 
99  if (!m_return_condition)
100  m_return_condition = new TCondition;
101 
102  m_return_condition->GetMutex()->Lock();
103 
104  post_request();
105 
106  m_return_condition->Wait();
107  m_return_condition->GetMutex()->UnLock();
108 }
109 
110 
111 //==============================================================================
112 
113 class RootSig2XTReqHandler : public TSignalHandler
114 {
115 private:
116  class XTReqTimer : public TTimer
117  {
118  public:
119  XTReqTimer() : TTimer() {}
120  virtual ~XTReqTimer() {}
121 
122  void FireAway()
123  {
124  Reset();
125  gSystem->AddTimer(this);
126  }
127 
128  virtual Bool_t Notify()
129  {
130  gSystem->RemoveTimer(this);
132  return kTRUE;
133  }
134  };
135 
137 
138 public:
139  RootSig2XTReqHandler() : TSignalHandler(kSigUser1), mTimer() { Add(); }
141 
142  virtual Bool_t Notify()
143  {
144  printf("Usr1 Woof Woof in Root thread! Starting Timer.\n");
145  mTimer.FireAway();
146  return kTRUE;
147  }
148 };
149 
150 //------------------------------------------------------------------------------
151 
152 void TRootXTReq::Bootstrap(pthread_t root_thread)
153 {
154  static const TString _eh("TRootXTReq::Bootstrap ");
155 
156  if (sRootThread != 0)
157  throw _eh + "Already initialized.";
158 
159  sRootThread = root_thread;
160  sQueueMutex = new TMutex(kTRUE);
162 }
163 
165 {
166  static const TString _eh("TRootXTReq::Shutdown ");
167 
168  if (sRootThread == 0)
169  throw _eh + "Have not beem initialized.";
170 
171  // Should lock and drain queue ... or sth.
172 
173  sRootThread = 0;
174  delete sSigHandler; sSigHandler = 0;
175  delete sQueueMutex; sQueueMutex = 0;
176 }
177 
179 {
180  printf("Timer fired, processing queue.\n");
181 
182  while (true)
183  {
184  TRootXTReq *req = 0;
185  {
186  TLockGuard _lck(sQueueMutex);
187 
188  if ( ! sQueue.empty())
189  {
190  req = sQueue.front();
191  sQueue.pop_front();
192  }
193  else
194  {
195  sSheduled = false;
196  break;
197  }
198  }
199 
200  req->Act();
201 
202  if (req->m_return_condition)
203  {
204  req->m_return_condition->GetMutex()->Lock();
205  req->m_return_condition->Signal();
206  req->m_return_condition->GetMutex()->UnLock();
207  }
208  else
209  {
210  delete req;
211  }
212  }
213 }
virtual Bool_t Notify()
Definition: TRootXTReq.cc:142
TCondition * m_return_condition
Definition: TRootXTReq.h:23
static void Bootstrap(pthread_t root_thread)
Definition: TRootXTReq.cc:152
void post_request()
Definition: TRootXTReq.cc:63
virtual ~TRootXTReq()
Definition: TRootXTReq.cc:56
virtual void Act()=0
static pthread_t sRootThread
Definition: TRootXTReq.h:26
static lpXTReq_t sQueue
Definition: TRootXTReq.h:25
static bool sSheduled
Definition: TRootXTReq.h:29
virtual ~RootSig2XTReqHandler()
Definition: TRootXTReq.cc:140
TRootXTReq(const char *n="TRootXTReq")
Definition: TRootXTReq.cc:51
static void Shutdown()
Definition: TRootXTReq.cc:164
std::list< TRootXTReq * > lpXTReq_t
Definition: TRootXTReq.h:21
static TSignalHandler * sSigHandler
Definition: TRootXTReq.h:28
void ShootRequest()
Definition: TRootXTReq.cc:76
static void ProcessQueue()
Definition: TRootXTReq.cc:178
void Reset(std::vector< TH2F > &depth)
void ShootRequestAndWait()
Definition: TRootXTReq.cc:91
static TMutex * sQueueMutex
Definition: TRootXTReq.h:27