title: qt signal/slot and pthreads dont play well together
body: <p>Can someone tell me why this qt code will not call the Callback when ASYNC_TIMERS is defined (ie m_timer.start is called from the pthread but the slot never runs). Obviously it is to do with being called from a pthread as it works when ASYNC_TIMERS is not defined but I want to know how to fix it from the pthread. I have tryed many things found on the net including moveToThread(), calling the threads run which calls exec() but I have had no luck on this problem?</p>
  
  <p>Cheers</p>
  
  <p>multitimer.h:</p>
  
  <pre><code>#pragma once
  
  #ifndef MULTI_TIMER_H
  #define MULTI_TIMER_H
  
  #include &lt;QThread&gt;
  #include &lt;QTimer&gt;
  #include &lt;QMutex&gt;
  
  #include &lt;QMap&gt;
  
  
  #include &lt;QMetaType&gt;
  #include &lt;cassert&gt;
  
  
  class MultiTimer : public QThread
  {
      Q_OBJECT
  
  public:
      typedef void (*multiTimerCallback)(quint32 p_id);
  
  private:
      QTimer m_timer;
      QMutex m_mutex;
      quint32 m_id;
      multiTimerCallback m_callback;
      void KillTimer(void);
  
  public:
      // only TimerFactory is allowed to instantiate MultiTimer
      MultiTimer(quint32 p_id, multiTimerCallback p_callback);
      ~MultiTimer();
      enum TTimerType
      {
          TT_SingleShot,      ///&lt; Timer fires only once
          TT_Repetitive       ///&lt; Timer keeps firing repeatedly until stopped with KillTimer()
      };
      void SetTimer(quint32 p_delayInMilliseconds, MultiTimer::TTimerType timerType);
  
  private slots:
      void Update(void);
  };
  
  #endif
  </code></pre>
  
  <p>timer.cpp:</p>
  
  <pre><code>#include &lt;QtCore/QCoreApplication&gt;
  #include "multitimer.h"
  #include &lt;stdio.h&gt;
  
  
  //--------------------------------------------------------------------------------------------------
  
  void MultiTimer::SetTimer(quint32 p_delayInMilliseconds, MultiTimer::TTimerType timerType)
  {
      QMutexLocker locker(&amp;m_mutex);
  
      m_timer.setSingleShot(TT_SingleShot == timerType ? true : false);
      m_timer.start(p_delayInMilliseconds);
      //QTimer::singleShot(p_delayInMilliseconds, this,SLOT(Update()));
  }
  
  void MultiTimer::KillTimer(void)
  {
      QMutexLocker locker(&amp;m_mutex);
      m_timer.stop();
  }
  
  void MultiTimer::Update(void)
  {
      QMutexLocker locker(&amp;m_mutex);
  
      if (NULL != m_callback)
          m_callback(m_id);
  }
  
  MultiTimer::MultiTimer(quint32 p_id, multiTimerCallback p_callback)
      : m_id(p_id)
      , m_callback(p_callback)
  {
      bool isConnected = true;
      isConnected &amp;= this-&gt;connect(&amp;this-&gt;m_timer, SIGNAL(timeout()), this, SLOT(Update()), Qt::QueuedConnection);
      assert(isConnected);
      //this-&gt;start();
  }
  
  MultiTimer::~MultiTimer()
  {
      KillTimer();
      wait();
  }
  
  
  //--------------------------------------------------------------------------------------------------
  #define ASYNC_TIMERS
  #define GLOBAL_TIMERS
  
  void Callback(quint32 p_id)
  {
      printf("Got timered by timer %d.\n", p_id);
  }
  
  MultiTimer *mt;
  void StartTimers(void)
  {
      #ifndef GLOBAL_TIMERS
      mt = new MultiTimer(1, Callback);
      #endif
      mt-&gt;SetTimer(1000, MultiTimer::TT_SingleShot);
  }
  
  #ifdef ASYNC_TIMERS
  pthread_t AsyncTaskThread;
  void *ProcessAsyncTasks(void */*ptr*/)
  {
      StartTimers();
      return NULL;
  }
  #endif
  
  int main(int argc, char *argv[])
  {
      QCoreApplication a(argc, argv);
  
      #ifdef GLOBAL_TIMERS
      mt = new MultiTimer(1, Callback);
      #endif
  
      #ifdef ASYNC_TIMERS
      pthread_create(&amp;AsyncTaskThread, NULL, &amp;ProcessAsyncTasks, NULL);
      #else
      StartTimers();
      #endif
  
      return a.exec();
  }
  </code></pre>