title: Multithreaded timer class
body: <p>I've created a timer class that performs a user supplied action (function that takes no arguments has no return type) at a user supplied interval. This action should be performed in its own thread--i.e. when the timer is created, a new thread is created, and that thread consists of a loop that uses <code>sigwait</code> to wait for the signal to come in before performing the callback.  The signal I want to use will be anywhere from <code>SIGRTMIN</code> to <code>SIGRTMAX</code>. I want to be able to create multiple timer objects which means multiple threads and multiple signals (one thread and signal per timer).  Using <a href="https://stackoverflow.com/questions/7809987/c-how-to-define-a-class-method-as-a-start-routine-to-thread-with-pthread-lib">this post</a>, the <code>timer_create</code> <a href="http://man7.org/linux/man-pages/man2/timer_create.2.html" rel="nofollow noreferrer">man page</a>, and <code>pthread_sigmask</code> <a href="http://man7.org/linux/man-pages/man3/pthread_sigmask.3.html" rel="nofollow noreferrer">man page</a> as references, this is what I have:</p>
  
  <pre><code>//timer.h
  #ifndef TIMERS_H
  #define TIMERS_H
  #include &lt;signal.h&gt;
  #include &lt;time.h&gt;
  #include &lt;inttypes.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;pthread.h&gt;
  
  class CTimer
  {
  public:
      CTimer(uint64_t period_ms, void(*callback)(void), int sig );
  private:
      typedef void (*Callback)(void);
      Callback m_pCallback;
      timer_t timerID;
      struct sigevent sev;
      struct itimerspec its;
      struct sigaction sa;
      uint8_t timerNum;
  
      pthread_t thread_id;
      sigset_t set;
      int signal_ID;
      void* loop();
  
      friend void* run_loop(void* arg);
  };
  #endif // TIMERS_H
  </code></pre>
  
  <p>and</p>
  
  <pre><code>//timer.cpp
  #include "timers.h"
  
  void* run_loop(void* arg)
  {
      return static_cast&lt;CTimer*&gt;(arg)-&gt;loop();
  }
  
  CTimer::CTimer(uint64_t period_ms, void(*callback)(void), int sig):
                 m_pCallback(callback), signal_ID(sig)
  {
      //create mask to send appropriate signal to thread
      int s;
      sigemptyset(&amp;set);
      s = sigaddset(&amp;set, signal_ID);
      if (s != 0)
      {
          printf("error on sigaddset\n");
      }
      s = pthread_sigmask(SIG_BLOCK, &amp;set, NULL);
      if (s != 0)
      {
          printf("error on pthread_sigmask\n");
      }
      //create new thread that will run the signal handler
      s = pthread_create(&amp;thread_id, NULL, run_loop, this);
      if (s != 0)
      {
          printf("error on pthread_create\n");
      }
  
      sev.sigev_notify = SIGEV_SIGNAL;
      sev.sigev_signo = signal_ID;
      sev.sigev_value.sival_ptr = &amp;timerID;
      if (timer_create(CLOCK_REALTIME, &amp;sev, &amp;timerID) == -1)
      {
          printf("error on timer create\n");
      }
      its.it_value.tv_sec = period_ms / 1000;
      its.it_value.tv_nsec = period_ms % 1000;
      its.it_interval.tv_sec = its.it_value.tv_sec;
      its.it_interval.tv_nsec = its.it_value.tv_nsec;
  
      if (timer_settime(timerID, 0, &amp;its, NULL) == -1)
      {
          printf("error on timer settime\n");
      }
  }
  
  void* CTimer::loop()
  {
      int s = 0;
      while (1)
      {
          s = sigwait(&amp;set, &amp;signal_ID);
          m_pCallback();
      }
  }
  </code></pre>
  
  <p>For testing I am using this:</p>
  
  <pre><code>//driver.cpp
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include "sys/time.h"
  #include "timers.h"
  
  uint64_t get_time_usec()
  {
      static struct timeval _time_stamp;
      gettimeofday(&amp;_time_stamp, NULL);
      return _time_stamp.tv_sec*1000000 + _time_stamp.tv_usec;
  }
  
  void callbacktest1()
  {
      printf("tick1 %" PRIu64 " \n", get_time_usec());
  }
  
  void callbacktest2()
  {
      printf("tick2 %" PRIu64 " \n", get_time_usec());
  }
  
  int main(int argv, char *argc[])
  {
      CTimer t1(1000, callbacktest1, SIGRTMIN);
      CTimer t2(2000, callbacktest2, SIGRTMIN+1);
  
      pause();
  }
  </code></pre>
  
  <p>When running, it will crash pretty quickly with the error "Real-time signal 1".  If I run it in gdb, I get</p>
  
  <pre><code>Starting program: /home/overlord/MySource/Timer/driver 
  [Thread debugging using libthread_db enabled]
  Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
  [New Thread 0x7ffff75ee700 (LWP 21455)]
  [New Thread 0x7ffff6ded700 (LWP 21456)]
  tick1 1477336403700925 
  tick1 1477336404700920 
  
  Program received signal SIG35, Real-time event 35.
  [Switching to Thread 0x7ffff75ee700 (LWP 21455)]
  0x00007ffff7bcc0c1 in do_sigwait (sig=0x7fffffffdbc8, set=&lt;optimized out&gt;) at ../nptl/sysdeps/unix/sysv/linux/../../../../../sysdeps/unix/sysv/linux/sigwait.c:60
  60      ../nptl/sysdeps/unix/sysv/linux/../../../../../sysdeps/unix/sysv/linux/sigwait.c: No such file or directory.
  </code></pre>
  
  <p>which is interesting because 35 is what SIGRTMIN+1 is equal to. So maybe I'm not routing the signals correctly? If I only create once instance of the timer in the driver.cpp file, things appear to work ok.  Any thoughts are appreciated.</p>
  
  <p>I'm also curious if this is even the right approach to what I'm trying to do.  In some brief tests I did, using the system signals seems way more stable than using sleep and usleep to burn up unused loop time.</p>