Common::Event: Implement in terms of Common::Flag to get rid of a volatile and optimize with early returns and atomic swaps

This commit is contained in:
Pierre Bourdon 2014-04-14 01:42:03 +02:00
parent e24cad0780
commit 48bd904028
1 changed files with 10 additions and 12 deletions

View File

@ -12,6 +12,7 @@
#pragma once #pragma once
#include "Common/Flag.h"
#include "Common/StdConditionVariable.h" #include "Common/StdConditionVariable.h"
#include "Common/StdMutex.h" #include "Common/StdMutex.h"
@ -20,38 +21,35 @@ namespace Common {
class Event class Event
{ {
public: public:
Event()
: is_set(false)
{}
void Set() void Set()
{ {
std::lock_guard<std::mutex> lk(m_mutex); if (m_flag.TestAndSet())
if (!is_set)
{ {
is_set = true; std::lock_guard<std::mutex> lk(m_mutex);
m_condvar.notify_one(); m_condvar.notify_one();
} }
} }
void Wait() void Wait()
{ {
if (m_flag.TestAndClear())
return;
std::unique_lock<std::mutex> lk(m_mutex); std::unique_lock<std::mutex> lk(m_mutex);
m_condvar.wait(lk, [&]{ return is_set; }); m_condvar.wait(lk, [&]{ return m_flag.IsSet(); });
is_set = false; m_flag.Clear();
} }
void Reset() void Reset()
{ {
std::unique_lock<std::mutex> lk(m_mutex);
// no other action required, since wait loops on // no other action required, since wait loops on
// the predicate and any lingering signal will get // the predicate and any lingering signal will get
// cleared on the first iteration // cleared on the first iteration
is_set = false; m_flag.Clear();
} }
private: private:
volatile bool is_set; Flag m_flag;
std::condition_variable m_condvar; std::condition_variable m_condvar;
std::mutex m_mutex; std::mutex m_mutex;
}; };