summaryrefslogtreecommitdiffstats
path: root/src/OSSupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/OSSupport')
-rw-r--r--src/OSSupport/Event.cpp56
-rw-r--r--src/OSSupport/Event.h11
-rw-r--r--src/OSSupport/IsThread.cpp4
-rw-r--r--src/OSSupport/IsThread.h15
4 files changed, 40 insertions, 46 deletions
diff --git a/src/OSSupport/Event.cpp b/src/OSSupport/Event.cpp
index 38144ead3..4c2adea3c 100644
--- a/src/OSSupport/Event.cpp
+++ b/src/OSSupport/Event.cpp
@@ -13,7 +13,7 @@
cEvent::cEvent(void) :
- m_ShouldWait(true)
+ m_ShouldContinue(false)
{
}
@@ -23,12 +23,11 @@ cEvent::cEvent(void) :
void cEvent::Wait(void)
{
- std::unique_lock<std::mutex> Lock(m_Mutex);
- while (m_ShouldWait)
{
- m_CondVar.wait(Lock);
+ std::unique_lock<std::mutex> Lock(m_Mutex);
+ m_CondVar.wait(Lock, [this](){ return m_ShouldContinue.load(); });
}
- m_ShouldWait = true;
+ m_ShouldContinue = false;
}
@@ -38,33 +37,13 @@ void cEvent::Wait(void)
bool cEvent::Wait(unsigned a_TimeoutMSec)
{
auto dst = std::chrono::system_clock::now() + std::chrono::milliseconds(a_TimeoutMSec);
- std::unique_lock<std::mutex> Lock(m_Mutex); // We assume that this lock is acquired without much delay - we are the only user of the mutex
- while (m_ShouldWait && (std::chrono::system_clock::now() <= dst))
+ bool Result;
{
- switch (m_CondVar.wait_until(Lock, dst))
- {
- case std::cv_status::no_timeout:
- {
- // The wait was successful, check for spurious wakeup:
- if (!m_ShouldWait)
- {
- m_ShouldWait = true;
- return true;
- }
- // This was a spurious wakeup, wait again:
- continue;
- }
-
- case std::cv_status::timeout:
- {
- // The wait timed out, return failure:
- return false;
- }
- } // switch (wait_until())
- } // while (m_ShouldWait && not timeout)
-
- // The wait timed out in the while condition:
- return false;
+ std::unique_lock<std::mutex> Lock(m_Mutex); // We assume that this lock is acquired without much delay - we are the only user of the mutex
+ Result = m_CondVar.wait_until(Lock, dst, [this](){ return m_ShouldContinue.load(); });
+ }
+ m_ShouldContinue = false;
+ return Result;
}
@@ -73,13 +52,20 @@ bool cEvent::Wait(unsigned a_TimeoutMSec)
void cEvent::Set(void)
{
- {
- std::unique_lock<std::mutex> Lock(m_Mutex);
- m_ShouldWait = false;
- }
+ m_ShouldContinue = true;
m_CondVar.notify_one();
}
+void cEvent::SetAll(void)
+{
+ m_ShouldContinue = true;
+ m_CondVar.notify_all();
+}
+
+
+
+
+
diff --git a/src/OSSupport/Event.h b/src/OSSupport/Event.h
index 572388a3f..2c58ba485 100644
--- a/src/OSSupport/Event.h
+++ b/src/OSSupport/Event.h
@@ -12,6 +12,7 @@
#include <mutex>
#include <condition_variable>
+#include <atomic>
@@ -28,7 +29,11 @@ public:
/** Sets the event - releases one thread that has been waiting in Wait().
If there was no thread waiting, the next call to Wait() will not block. */
- void Set (void);
+ void Set(void);
+
+ /** Sets the event - releases all threads that have been waiting in Wait().
+ If there was no thread waiting, the next call to Wait() will not block. */
+ void SetAll(void);
/** Waits for the event until either it is signalled, or the (relative) timeout is passed.
Returns true if the event was signalled, false if the timeout was hit or there was an error. */
@@ -37,9 +42,9 @@ public:
private:
/** Used for checking for spurious wakeups. */
- bool m_ShouldWait;
+ std::atomic<bool> m_ShouldContinue;
- /** Mutex protecting m_ShouldWait from multithreaded access. */
+ /** Mutex protecting m_ShouldContinue from multithreaded access. */
std::mutex m_Mutex;
/** The condition variable used as the Event. */
diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp
index 55e96b622..e295d5f25 100644
--- a/src/OSSupport/IsThread.cpp
+++ b/src/OSSupport/IsThread.cpp
@@ -134,9 +134,9 @@ bool cIsThread::Wait(void)
m_Thread.join();
return true;
}
- catch (std::system_error & a_Exception)
+ catch (const std::system_error & a_Exception)
{
- LOGERROR("cIsThread::Wait error %i: could not join thread %s; %s", a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str());
+ LOGERROR("%s error %i: could not join thread %s; %s", __FUNCTION__, a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str());
return false;
}
}
diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h
index f642c8724..fa6813cd7 100644
--- a/src/OSSupport/IsThread.h
+++ b/src/OSSupport/IsThread.h
@@ -32,10 +32,6 @@ protected:
/** The overriden Execute() method should check this value periodically and terminate if this is true. */
volatile bool m_ShouldTerminate;
-private:
- /** Wrapper for Execute() that waits for the initialization event, to prevent race conditions in thread initialization. */
- void DoExecute(void);
-
public:
cIsThread(const AString & a_ThreadName);
virtual ~cIsThread();
@@ -51,14 +47,21 @@ public:
/** Returns true if the thread calling this function is the thread contained within this object. */
bool IsCurrentThread(void) const { return std::this_thread::get_id() == m_Thread.get_id(); }
+
+private:
-protected:
+ /** The name of the thread, used to aid debugging in IDEs which support named threads */
AString m_ThreadName;
+
+ /** The thread object which holds the created thread for later manipulation */
std::thread m_Thread;
/** The event that is used to wait with the thread's execution until the thread object is fully initialized.
- This prevents the IsCurrentThread() call to fail because of a race-condition. */
+ This prevents the IsCurrentThread() call to fail because of a race-condition where the thread starts before m_Thread has been fully assigned. */
cEvent m_evtStart;
+
+ /** Wrapper for Execute() that waits for the initialization event, to prevent race conditions in thread initialization. */
+ void DoExecute(void);
} ;