CARMA C++
GenericMasterTask.h
Go to the documentation of this file.
1 #ifndef SZA_UTIL_GENERICMASTERTASK_H
2 #define SZA_UTIL_GENERICMASTERTASK_H
3 
11 #include <string>
12 
16 #include "carma/szautil/TimeVal.h"
17 
18 namespace sza {
19  namespace util {
20 
21  template<class Msg>
22  class GenericMasterTask :
23  public sza::util::GenericTask<Msg> {
24 
25  public:
26 
30  GenericMasterTask();
31 
35  virtual ~GenericMasterTask();
36 
37  static void signalHandler(int sigNo);
38 
39  protected:
40 
41  static GenericMasterTask<Msg>* masterTask_;
42 
46  sza::util::SignalTask* signal_;
47 
51  void processTaskMsg(bool* stop);
52 
57  void sendInstallTimerMsg(std::string name, int sigNo,
58  unsigned long intervalSec,
59  unsigned long intervalNsec,
60  SIGNALTASK_HANDLER_FN(*handler));
61 
65  void sendInstallTimerMsg(std::string name, int sigNo,
66  unsigned long initSec,
67  unsigned long initNsec,
68  unsigned long intervalSec,
69  unsigned long intervalNsec,
70  SIGNALTASK_HANDLER_FN(*handler));
71 
75  void installTimer(Msg* msg);
76 
80  virtual void installTimers();
81 
85  void sendInstallSignalMsg(int sigNo, SIGNALTASK_HANDLER_FN(*handler));
86 
90  void installSignal(Msg* msg);
91 
95  virtual void installSignals();
96 
100  void sendEnableTimerMsg(std::string name, bool enable);
101 
105  void enableTimer(Msg* msg);
106 
110  void sendAddHandlerMsg(std::string name,
111  SIGNALTASK_HANDLER_FN(*handler),
112  bool add);
113 
117  void addHandler(Msg* msg);
118 
119  }; // End class GenericMasterTask
120 
121  // Template functions must be defined in the header file
122 
123  template<class Msg>
124  GenericMasterTask<Msg>* GenericMasterTask<Msg>::masterTask_ = 0;
125 
126  /*
127  * Constructor
128  */
129  template<class Msg>
130  GenericMasterTask<Msg>::GenericMasterTask() :
131  GenericTask<Msg>::GenericTask()
132  {
133  DBPRINT(true, Debug::DEBUG7, "Inside MasterTask constructor");
134  signal_ = 0;
135  masterTask_ = this;
136  };
137 
138  /*
139  * Detructor
140  */
141  template<class Msg>
142  GenericMasterTask<Msg>::~GenericMasterTask() {};
143 
147  template<class Msg>
148  void GenericMasterTask<Msg>::processTaskMsg(bool* stop)
149  {
150  Msg msg;
151 
152  GenericTask<Msg>::msgq_.readMsg(&msg);
153 
154  switch (msg.genericMsgType_) {
155  case Msg::HEARTBEAT: // Is this a heartbeat request?
157  break;
158  case Msg::RESTART: // Is this a request to restart?
160  break;
161  case Msg::STOP: // Did we receive a request to shut
162  // down?
163  *stop = true;
164  break;
165  default:
166  {
168  (GenericMasterTaskMsg::GenericMasterMsgType)msg.genericMsgType_;
169  switch(type) {
170  case Msg::INSTALL_TIMER:
171  installTimer(&msg);
172  break;
173  case Msg::INSTALL_SIGNAL:
174  DBPRINT(true, Debug::DEBUG31, "Got an install signal message");
175  installSignal(&msg);
176  break;
177  case Msg::ADD_HANDLER:
178  addHandler(&msg);
179  break;
180  case Msg::ENABLE_TIMER:
181  DBPRINT(true, Debug::DEBUG10, "Got an enable timer message");
182  enableTimer(&msg);
183  break;
184  default: // Else forward this message to the task-specific
185  // process method
186  this->processMsg(&msg);
187  break;
188  }
189  }
190  }
191  };
192 
196  template<class Msg>
197  void GenericMasterTask<Msg>::sendInstallTimerMsg(std::string name, int sigNo,
198  unsigned long initSec,
199  unsigned long initNsec,
200  unsigned long intervalSec,
201  unsigned long intervalNsec,
202  SIGNALTASK_HANDLER_FN(*handler))
203  {
204  DBPRINT(true, DEBUG_SIGNAL, "Inside");
205 
206  Msg msg;
207 
208  msg.packInstallTimerMsg(name, sigNo,
209  initSec, initNsec,
210  intervalSec, intervalNsec,
211  handler);
212 
213  this->sendTaskMsg(&msg);
214  }
215 
220  template<class Msg>
221  void GenericMasterTask<Msg>::sendInstallTimerMsg(std::string name, int sigNo,
222  unsigned long intervalSec,
223  unsigned long intervalNsec,
224  SIGNALTASK_HANDLER_FN(*handler))
225  {
226  DBPRINT(true, DEBUG_SIGNAL, "Inside");
227 
228  Msg msg;
229 
230  msg.packInstallTimerMsg(name, sigNo, intervalSec, intervalNsec, handler);
231 
232  this->sendTaskMsg(&msg);
233  }
234 
238  template<class Msg>
239  void GenericMasterTask<Msg>::installTimer(Msg* msg)
240  {
241  // Install the timer.
242 
243  COUT("Installing signalhandler for signal: " << msg->genericMasterBody.installTimer.sigNo << "(" << pthread_self() << ")");
244 
245  struct sigaction action;
246  sigfillset (&(action.sa_mask));
247  action.sa_restorer = NULL;
248  action.sa_handler = signalHandler;
249  sigaction (msg->genericMasterBody.installTimer.sigNo, &action, NULL);
250 
251  if(signal_ != 0)
252  signal_->sendInstallTimerMsg(msg->genericMasterBody.installTimer.name,
253  msg->genericMasterBody.installTimer.sigNo,
254  msg->genericMasterBody.installTimer.initSec,
255  msg->genericMasterBody.installTimer.initNsec,
256  msg->genericMasterBody.installTimer.intervalSec,
257  msg->genericMasterBody.installTimer.intervalNsec,
258  msg->genericMasterBody.installTimer.handler);
259  }
260 
264  template<class Msg>
265  void GenericMasterTask<Msg>::installTimers() {};
266 
270  template<class Msg>
271  void GenericMasterTask<Msg>::sendInstallSignalMsg(int sigNo,
272  SIGNALTASK_HANDLER_FN(*handler))
273  {
274  Msg msg;
275 
276  msg.packInstallSignalMsg(sigNo, handler);
277 
278  this->sendTaskMsg(&msg);
279  }
280 
284  template<class Msg>
285  void GenericMasterTask<Msg>::installSignal(Msg* msg)
286  {
287  // Set the action for this signal to call our signalHandler.
288  // Our signal handler will just forward the signal to the signal thread.
289 
290  COUT("Installing signalhandler for signal: " << msg->genericMasterBody.installSignal.sigNo << "(" << pthread_self() << ")");
291 
292  struct sigaction action;
293  sigfillset (&(action.sa_mask));
294  action.sa_restorer = NULL;
295  action.sa_handler = signalHandler;
296  sigaction (msg->genericMasterBody.installSignal.sigNo, &action, NULL);
297 
298  // And install the signal with the signal thread
299 
300  if(signal_)
301  signal_->sendInstallSignalMsg(msg->genericMasterBody.installSignal.sigNo,
302  msg->genericMasterBody.installSignal.handler);
303  }
304 
308  template<class Msg>
309  void GenericMasterTask<Msg>::installSignals() {};
310 
314  template<class Msg>
315  void GenericMasterTask<Msg>::sendEnableTimerMsg(std::string name, bool enable)
316  {
317  DBPRINT(true, Debug::DEBUG2, "Inside");
318 
319  Msg msg;
320 
321  msg.packEnableTimerMsg(name, enable);
322 
323  this->sendTaskMsg(&msg);
324  }
325 
329  template<class Msg>
330  void GenericMasterTask<Msg>::sendAddHandlerMsg(std::string name,
331  SIGNALTASK_HANDLER_FN(*handler),
332  bool add)
333  {
334  DBPRINT(true, Debug::DEBUG2, "Inside, name = " << name
335  << " add = " << add);
336  Msg msg;
337 
338  msg.packAddHandlerMsg(name, handler, add);
339 
340  this->sendTaskMsg(&msg);
341  }
342 
346  template<class Msg>
347  void GenericMasterTask<Msg>::enableTimer(Msg* msg)
348  {
349  DBPRINT(true, Debug::DEBUG2, "Signal_ is: "
350  << (signal_ == 0 ? "NULL" : "not NULL"));
351 
352  if(signal_ != 0)
353  signal_->sendEnableTimerMsg(msg->genericMasterBody.enableTimer.name,
354  msg->genericMasterBody.enableTimer.enable);
355  }
356 
360  template<class Msg>
361  void GenericMasterTask<Msg>::addHandler(Msg* msg)
362  {
363  if(Debug::debugging(DEBUG_DELAY)) {
364  sza::util::TimeVal timeVal;
365  timeVal.setToCurrentTime();
366  DBPRINT(true, DEBUG_DELAY,
367  "Adding a handler to: " << msg->genericMasterBody.addHandler.name << " "
368  << timeVal.getSeconds());
369  }
370 
371  DBPRINT(true, Debug::DEBUG2, "Signal_ is: "
372  << (signal_ == 0 ? "NULL" : "not NULL"));
373 
374  if(signal_ != 0)
375  signal_->sendAddHandlerMsg(msg->genericMasterBody.addHandler.name,
376  msg->genericMasterBody.addHandler.handler,
377  msg->genericMasterBody.addHandler.add);
378  }
379 
383  template<class Msg>
384  void GenericMasterTask<Msg>::signalHandler(int sigNo)
385  {
386  if(masterTask_) {
387  if(masterTask_->signal_) {
388  pthread_kill(masterTask_->signal_->getThreadId(), sigNo);
389  }
390  }
391  }
392 
393 
394  } // End namespace util
395 } // End namespace sza
396 
397 
398 
399 #endif // End #ifndef SZA_UTIL_GENERICMASTERTASK_H
void setToCurrentTime(clockid_t clock=CLOCK_REALTIME)
Fill this structure with the current time from the specified clock.
A class for managing timeval/timespec structs.
Definition: TimeVal.h:53
Tagged: Fri Nov 14 12:39:34 UTC 2003.
Tagged: Fri Nov 14 12:39:33 UTC 2003.
unsigned long getSeconds()
Return just the integer seconds.
Tagged: Fri Nov 14 12:39:38 UTC 2003.
virtual void restart(void)
Restart this thread.
Definition: GenericTask.h:329
All tasks will have the following functionality:
Definition: GenericTask.h:32
virtual void respondToHeartBeat()
Respond to a heartbeat message.
Definition: GenericTask.h:413
Tagged: Fri Nov 14 12:39:36 UTC 2003.
A generic base-class task for handling timers &amp; signals.
Definition: SignalTask.h:55
GenericMasterMsgType
Enumerate supported generic message types.