add NotifiableThread

This commit is contained in:
John-Michael Baier
2020-12-06 16:28:12 +01:00
parent b00aec4611
commit b5616c1126
2 changed files with 67 additions and 9 deletions
+34 -5
View File
@@ -84,25 +84,54 @@ WaitThread::~WaitThread() {
void WaitThread::stop() { void WaitThread::stop() {
pthread_mutex_lock(&m_mutex); pthread_mutex_lock(&m_mutex);
pthread_cond_signal(&m_cond); pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex);
Thread::stop(); Thread::stop();
pthread_mutex_unlock(&m_mutex);
} }
bool WaitThread::join() { bool WaitThread::join() {
pthread_mutex_lock(&m_mutex); stop();
pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex);
return Thread::join(); return Thread::join();
} }
bool WaitThread::Wait(int seconds) { bool WaitThread::Wait(int seconds) {
pthread_mutex_lock(&m_mutex);
struct timespec t; struct timespec t;
clockGettime(&t); clockGettime(&t);
t.tv_sec += seconds; t.tv_sec += seconds;
pthread_mutex_lock(&m_mutex);
pthread_cond_timedwait(&m_cond, &m_mutex, &t); pthread_cond_timedwait(&m_cond, &m_mutex, &t);
pthread_mutex_unlock(&m_mutex); pthread_mutex_unlock(&m_mutex);
return isRunning(); return isRunning();
} }
NotifiableThread::NotifiableThread()
: WaitThread(), m_notified(false) {
}
void NotifiableThread::notify() {
pthread_mutex_lock(&m_mutex);
pthread_cond_signal(&m_cond);
m_notified = true;
pthread_mutex_unlock(&m_mutex);
}
bool NotifiableThread::waitNotified(int millis) {
pthread_mutex_lock(&m_mutex);
if (!m_notified) {
struct timespec t;
clockGettime(&t);
t.tv_sec += millis / 1000000000;
t.tv_nsec += (millis % 1000000000) * 1000000;
if (t.tv_nsec > 1000000000) {
t.tv_sec++;
t.tv_nsec -= 1000000000;
}
pthread_cond_timedwait(&m_cond, &m_mutex, &t);
}
bool notified = m_notified;
m_notified = false;
pthread_mutex_unlock(&m_mutex);
return notified;
}
} // namespace ebusd } // namespace ebusd
+33 -4
View File
@@ -1,6 +1,6 @@
/* /*
* ebusd - daemon for communication with eBUS heating systems. * ebusd - daemon for communication with eBUS heating systems.
* Copyright (C) 2014-2018 John Baier <ebusd@ebusd.eu>, Roland Jax 2012-2014 <ebusd@liwest.at> * Copyright (C) 2014-2020 John Baier <ebusd@ebusd.eu>, Roland Jax 2012-2014 <ebusd@liwest.at>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@ namespace ebusd {
/** \file lib/utils/thread.h */ /** \file lib/utils/thread.h */
/** /**
* wrapper class for pthread. * Wrapper class for pthread.
*/ */
class Thread { class Thread {
public: public:
@@ -82,7 +82,7 @@ class Thread {
/** /**
* Thread entry method to be overridden by derived class. * Thread entry method to be overridden by derived class.
*/ */
virtual void run() = 0; virtual void run() = 0; // abstract
private: private:
@@ -134,7 +134,7 @@ class WaitThread : public Thread {
bool Wait(int seconds); bool Wait(int seconds);
private: protected:
/** the mutex for waiting. */ /** the mutex for waiting. */
pthread_mutex_t m_mutex; pthread_mutex_t m_mutex;
@@ -143,6 +143,35 @@ class WaitThread : public Thread {
}; };
/**
* A @a WaitThread that can be waited on.
*/
class NotifiableThread : public WaitThread {
public:
/**
* Constructor.
*/
NotifiableThread();
/**
* Notify another thread currently in @a wait().
*/
void notify();
/**
* Wait for getting notified up to the specified amount of time.
* @param millis the maximum number of milliseconds to wait.
* @return true if @a notify() was called while waiting.
*/
bool waitNotified(int millis);
private:
/** whether @a notify() was called while waiting. */
bool m_notified;
};
/** /**
* A simple mutex. * A simple mutex.
*/ */