Permalink
Browse files

Change MythSignalingTimer to use QWaitCondition

When you do a MythSignalingTimer::stop(), the method would not return until
the next timer expiry.  This is an issue as I'm using it for a QTimer
replacement with a 5 minute timer...  Changed it to use QWaitCondition such
that it is interrupted nearly immediately when ::stop() is run.  Also, unlock
the mutex before running wait() as this avoids a deadlock.

Also changed the locking in the loggingserver to avoid more possible
deadlock situations.
  • Loading branch information...
1 parent 2b189a9 commit 25478deae45312f2ae2fa54ef2ea087392268c4d @Beirdo Beirdo committed Jun 18, 2012
@@ -748,7 +748,9 @@ void LogServerThread::checkHeartBeats(void)
{
qlonglong epoch;
+ // cout << "pre-lock 1" << endl;
QMutexLocker lock(&logClientMapMutex);
+ // cout << "pre-lock 2" << endl;
QMutexLocker lock2(&logClientToDelMutex);
loggingGetTimeStamp(&epoch, NULL);
@@ -1091,6 +1093,8 @@ void LogForwardThread::expireClients(void)
LOG(VB_GENERAL, LOG_INFO, QString("Expiring client %1 (#%2)")
.arg(clientId).arg(logClientCount));
LoggerListItem *item = logClientMap.take(clientId);
+ if (!item)
+ continue;
LoggerList *list = item->list;
delete item;
@@ -1171,8 +1175,9 @@ void LogForwardThread::forwardMessage(LogMessage *msg)
if (json.size() == 0)
{
// This is either a ping response or a first gasp
- QMutexLocker lock(&logClientMapMutex);
+ logClientMapMutex.lock();
LoggerListItem *logItem = logClientMap.value(clientId, NULL);
+ logClientMapMutex.unlock();
if (!logItem)
{
// Send an initial ping so the client knows we are in the house
@@ -23,7 +23,7 @@
MythSignalingTimer::MythSignalingTimer(
QObject *parent, const char *slot) :
QObject(parent), MThread("SignalingTimer"),
- dorun(false), running(false), microsec(0)
+ dorun(false), running(false), millisec(0)
{
connect(this, SIGNAL(timeout()), parent, slot,
Qt::QueuedConnection);
@@ -40,7 +40,7 @@ void MythSignalingTimer::start(int msec)
if (msec <= 0)
return;
- microsec = 1000 * msec;
+ millisec = msec;
QMutexLocker locker(&startStopLock);
if (!running)
@@ -64,6 +64,8 @@ void MythSignalingTimer::stop(void)
if (running)
{
dorun = false;
+ timerWait.wakeAll();
+ locker.unlock();
wait();
}
}
@@ -74,8 +76,8 @@ void MythSignalingTimer::run(void)
RunProlog();
while (dorun)
{
- usleep(microsec);
- if (dorun)
+ QMutexLocker lock(&startStopLock);
+ if (dorun && !timerWait.wait(lock.mutex(), millisec))
emit timeout();
}
RunEpilog();
@@ -5,6 +5,7 @@
#include <stdint.h>
+#include <QWaitCondition>
#include <QMutex>
#include "mythbaseexp.h"
@@ -39,9 +40,10 @@ class MBASE_PUBLIC MythSignalingTimer : private QObject, private MThread
virtual void run(void);
QMutex startStopLock;
+ QWaitCondition timerWait;
volatile bool dorun;
volatile bool running;
- volatile uint64_t microsec;
+ volatile uint64_t millisec;
};
#endif // _MYTH_SIGNALING_TIMER_H_

0 comments on commit 25478de

Please sign in to comment.