SoDaRadio-5.0.3-master:8901fb5
SoDaBase.hxx
Go to the documentation of this file.
1 /*
2 Copyright (c) 2012,2013,2014 Matthew H. Reilly (kb1vc)
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9  Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in
13  the documentation and/or other materials provided with the
14  distribution.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #ifndef SODA_BASE_HDR
30 #define SODA_BASE_HDR
31 
32 #include "Command.hxx"
33 #include "MultiMBox.hxx"
34 #include "Debug.hxx"
35 #include <complex>
36 #include <string>
37 #include <boost/thread.hpp>
38 #include <boost/format.hpp>
39 #include <sys/types.h>
40 #include <unistd.h>
41 #include <sys/syscall.h>
42 
43 extern "C" {
44 #include <signal.h>
45 #include <stdio.h>
46 #include <unistd.h>
47 }
48 
59 namespace SoDa {
60 
72  class SoDaBuf : public MBoxMessage {
73  public:
79  SoDaBuf(unsigned int _size) {
80  maxlen = _size;
81  len = maxlen;
82  dat = new std::complex<float>[_size];
83  // we also overlay a floating point buffer in the same space.
84  fdat = (float *) dat;
85  maxflen = maxlen * 2;
86  flen = len * 2;
87  }
88 
89  bool copy(SoDaBuf * src) {
90  if(maxlen >= src->maxlen) {
91  flen = src->flen;
92  memcpy(fdat, src->fdat, sizeof(float) * flen);
93  return true;
94  }
95  else {
96  return false;
97  }
98  }
99 
101  unsigned int getComplexLen() { return len; }
103  unsigned int getComplexMaxLen() { return maxlen; }
104 
106  unsigned int getFloatLen() { return flen; }
108  unsigned int getFloatMaxLen() { return maxflen; }
109 
114  bool setComplexLen(unsigned int nl) {
115  if(nl > maxlen) return false;
116  len = nl;
117  return true;
118  }
119 
124  bool setFloatLen(unsigned int nl) {
125  if(nl > maxflen) return false;
126  flen = nl;
127  return true;
128  }
129 
133  std::complex<float> * getComplexBuf() { return dat; }
137  float * getFloatBuf() { return fdat; }
138 
139  private:
140  std::complex<float> * dat;
141  float * fdat;
142  unsigned int maxflen;
143  unsigned int flen;
144  unsigned int maxlen;
145  unsigned int len;
146  };
147 
156 
157 
167  class SoDaBase {
168  public:
176  SoDaBase(const std::string & oname);
177 
182  std::string & getObjName() { return objname; }
183 
190  SoDaBase * findSoDaObject(const std::string & oname);
191 
198  double getTime();
199 
200  private:
201  std::string objname;
202 
203  static bool first_time;
204  static double base_first_time;
205 
206  static std::map<std::string, SoDaBase * > ObjectDirectory;
207  };
208 
217  class SoDaException {
218  public:
225  SoDaException(const std::string & _reason, SoDaBase * obj = NULL)
226  {
227  thrower = obj;
228  reason = _reason;
229  }
236  SoDaException(const char * _reason, SoDaBase * obj) {
237  thrower = obj;
238  reason = std::string(_reason);
239  }
240 
241 
246  std::string toString() {
247  std::string ret;
248  if(thrower != NULL) {
249  ret = (boost::format("SoDa Object [%s] threw exception [%s]\n") % thrower->getObjName() % reason).str();
250  }
251  else {
252  ret = (boost::format("Unknown SoDa Object threw exception [%s]\n") % reason).str();
253  }
254 
255  return ret;
256  }
257 
262  const char * what() {
263  return toString().c_str();
264  }
265  private:
267  std::string reason;
268  };
269 
270 
284  class SoDaThread : public SoDaBase, public Debug {
285  public:
286  SoDaThread(const std::string & oname) : SoDaBase(oname), Debug(oname) {
287  th = NULL;
288  }
292  void start() {
293  if(th != NULL) return;
294  th = new boost::thread(&SoDaThread::outerRun, this);
295  }
296 
301  void join() {
302  th->join();
303  }
304 
313  bool waitForJoin(unsigned int m) {
314  return th->try_join_for(boost::chrono::milliseconds(m));
315  }
316 
317 
318 
324  virtual void run() = 0;
325 
335  void execCommand(Command * cmd)
336  {
337  switch (cmd->cmd) {
338  case Command::GET:
339  execGetCommand(cmd);
340  break;
341  case Command::SET:
342  execSetCommand(cmd);
343  break;
344  case Command::REP:
345  execRepCommand(cmd);
346  break;
347  default:
348  break;
349  }
350  }
351 
355  virtual void execGetCommand(Command * cmd) { (void) cmd; }
356 
360  virtual void execSetCommand(Command * cmd) { (void) cmd; }
361 
365  virtual void execRepCommand(Command * cmd) { (void) cmd; }
366 
367  private:
368  boost::thread * th;
369 
370 
376  void outerRun() {
377  hookSigSeg();
378  pid_t tid;
379  tid = syscall(SYS_gettid);
380  debugMsg(boost::format("%s starting as TID %x.\n") % getObjName() % tid);
381  try {
382  run();
383  }
384  catch (SoDaException exc) {
385  std::cerr << getObjName() << " caught " << exc.toString() << std::endl;
386  }
387  catch (SoDaException * exc) {
388  std::cerr << getObjName() << " caught " << exc->toString() << std::endl;
389  }
390  catch (const std::exception & e) {
391  std::cerr << getObjName() << " caught exception here: " << e.what() << std::endl;
392  }
393  catch (...) {
394  std::cerr << getObjName() << " caught unknown exception" << std::endl;
395  }
396  debugMsg(boost::format("%s terminating.\n") % getObjName());
397  }
398 
399  static void sigsegHandler(int sig)
400  {
401  std::cerr << "\n-----------"
402  << "\n-----------"
403  << "\n-----------"
404  << "\n-----------"
405  << " A SoDaThread caught a sig segv"
406  << "\n-----------"
407  << "\n-----------"
408  << "\n-----------"
409  << "\n-----------"
410  << std::endl;
411  // resignal
412  signal(sig, SIG_DFL);
413  kill(getpid(), SIGSEGV);
414  }
415 
416  void hookSigSeg() {
417  struct sigaction act;
418  sigemptyset(&act.sa_mask);
419  act.sa_handler = SoDaThread::sigsegHandler;
420  act.sa_flags = 0;
421  sigaction(SIGSEGV, &act, 0);
422  }
423 
424  };
425 }
426 
427 #endif
const char * what()
Create a string that explains this exception.
Definition: SoDaBase.hxx:262
virtual void execGetCommand(Command *cmd)
optional method to handle "GET" commands – commands that request a response
Definition: SoDaBase.hxx:355
The Thread baseclass for all SoDa thread objects.
Definition: SoDaBase.hxx:284
unsigned int maxflen
the maximum length in terms of real floats
Definition: SoDaBase.hxx:142
std::string & getObjName()
get the name of this object
Definition: SoDaBase.hxx:182
SoDaBuf(unsigned int _size)
constructor: Allocate a complex/real buffer of complex data values
Definition: SoDaBase.hxx:79
static void sigsegHandler(int sig)
Definition: SoDaBase.hxx:399
float * fdat
the storage array (REAL version) Storage is common to both types
Definition: SoDaBase.hxx:141
static bool first_time
have we seen the first call to getTime?
Definition: SoDaBase.hxx:203
The SoDa Exception class.
Definition: SoDaBase.hxx:217
SoDaBase * thrower
who caused the exception, if anyone?
Definition: SoDaBase.hxx:266
void start()
Execute the threads run loop.
Definition: SoDaBase.hxx:292
std::string toString()
Create a string that explains this exception.
Definition: SoDaBase.hxx:246
static std::map< std::string, SoDaBase *> ObjectDirectory
a class member – directory of all registered objects.
Definition: SoDaBase.hxx:206
unsigned int getComplexMaxLen()
Return the maximum number of complex float values that this buffer can hold.
Definition: SoDaBase.hxx:103
The Buffer Class.
Definition: SoDaBase.hxx:72
void join()
more properly "Wait for this thread to exit its run loop".
Definition: SoDaBase.hxx:301
bool setComplexLen(unsigned int nl)
set the length of the buffer (in number of complex floats.)
Definition: SoDaBase.hxx:114
static double base_first_time
time of first call to getTime from anyone.
Definition: SoDaBase.hxx:204
std::complex< float > * dat
the storage array (complex version) Storage is common to both types
Definition: SoDaBase.hxx:140
float * getFloatBuf()
Return a pointer to the storage buffer of floats.
Definition: SoDaBase.hxx:137
std::complex< float > * getComplexBuf()
Return a pointer to the storage buffer of complex floats.
Definition: SoDaBase.hxx:133
This is a list of all the commands that can "do something" to one or more components in the SoDa radi...
Definition: Command.hxx:47
virtual void execRepCommand(Command *cmd)
optional method that reports status or the result of some action.
Definition: SoDaBase.hxx:365
bool waitForJoin(unsigned int m)
wait for the thread to stop running, or the specified time to pass.
Definition: SoDaBase.hxx:313
A simple base class to provide debug messaging from any derived class.
Definition: Debug.hxx:42
SoDaThread(const std::string &oname)
Definition: SoDaBase.hxx:286
SoDaException(const char *_reason, SoDaBase *obj)
The constructor.
Definition: SoDaBase.hxx:236
std::string objname
the name of the object
Definition: SoDaBase.hxx:201
void outerRun()
the run method that is called by the boost thread handler.
Definition: SoDaBase.hxx:376
virtual void execSetCommand(Command *cmd)
optional method to handle "SET" commands – commands that set internal state in the object...
Definition: SoDaBase.hxx:360
MultiMBox< SoDaBuf > DatMBox
Mailboxes that carry float or complex data are of type DatMBox.
Definition: SoDaBase.hxx:155
CmdType cmd
the command type (SET, GET, REP)
Definition: Command.hxx:672
MultiMBox< Command > CmdMBox
Mailboxes that carry commands only are of type CmdMBox.
Definition: SoDaBase.hxx:151
unsigned int getComplexLen()
Return the number of complex float values in this buffer.
Definition: SoDaBase.hxx:101
unsigned int flen
the current length of the buffer in REAL fp values
Definition: SoDaBase.hxx:143
SoDaException(const std::string &_reason, SoDaBase *obj=NULL)
The constructor.
Definition: SoDaBase.hxx:225
std::string reason
what was the cause of the exception?
Definition: SoDaBase.hxx:267
unsigned int getFloatMaxLen()
Return the maximum number of float values that this buffer can hold.
Definition: SoDaBase.hxx:108
bool setFloatLen(unsigned int nl)
set the length of the buffer (in number of floats.)
Definition: SoDaBase.hxx:124
unsigned int getFloatLen()
Return the number of float values in this buffer.
Definition: SoDaBase.hxx:106
unsigned int maxlen
the maximum length in terms of complex floats
Definition: SoDaBase.hxx:144
The SoDa Base class.
Definition: SoDaBase.hxx:167
boost::thread * th
Definition: SoDaBase.hxx:368
void execCommand(Command *cmd)
Execute (dispatch) a message removed from the command stream to one of the basic Command handler func...
Definition: SoDaBase.hxx:335
bool copy(SoDaBuf *src)
Definition: SoDaBase.hxx:89
unsigned int len
the current length of the buffer in complex fp values
Definition: SoDaBase.hxx:145