message: Some improvement to ThreadingTools::Signal
diff: @@ -41,8 +41,8 @@ class Signal
  public:
  Signal()
  {
  - m_SignaledValue = 0;
  - m_NumThreadsAwaken = 0;
  + m_SignaledValue.store(0);
  + m_NumThreadsAwaken.store(0);
  }
  // http://en.cppreference.com/w/cpp/thread/condition_variable
  @@ -58,8 +58,8 @@ public:
  // std::condition_variable works only with std::unique_lock<std::mutex>
  std::lock_guard<std::mutex> Lock{m_Mutex};
  VERIFY(SignalValue != 0, "Signal value must not be 0");
  - VERIFY(m_SignaledValue == 0 && m_NumThreadsAwaken == 0, "Not all threads have been awaken since the signal was triggered last time, or the signal has not been reset");
  - m_SignaledValue = SignalValue;
  + VERIFY(m_SignaledValue.load() == 0 && m_NumThreadsAwaken.load() == 0, "Not all threads have been awaken since the signal was triggered last time, or the signal has not been reset");
  + m_SignaledValue.store(SignalValue);
  }
  // Unlocking is done before notifying, to avoid waking up the waiting
  // thread only to block again (see notify_one for details)
  @@ -87,22 +87,23 @@ public:
  std::unique_lock<std::mutex> Lock(m_Mutex);
  // It is safe to check m_SignaledValue since we are holding
  // the mutex
  - if (m_SignaledValue == 0)
  + if (m_SignaledValue.load() == 0)
  {
  - m_CondVar.wait(Lock, [&] { return m_SignaledValue != 0; });
  + m_CondVar.wait(Lock, [&] { return m_SignaledValue.load() != 0; });
  }
  - int SignaledValue = m_SignaledValue;
  - // Count the number of threads awaken while holding the mutex
  - ++m_NumThreadsAwaken;
  + auto SignaledValue = m_SignaledValue.load();
  + // Update the number of threads awaken while holding the mutex
  + const auto NumThreadsAwaken = m_NumThreadsAwaken.fetch_add(1) + 1;
  + // fetch_add returns the original value immediately preceding the addition.
  if (AutoReset)
  {
  VERIFY(NumThreadsWaiting > 0, "Number of waiting threads must not be 0 when auto resetting the signal");
  // Reset the signal while holding the mutex. If Trigger() is executed by another
  // thread, it will wait until we release the mutex
  - if (m_NumThreadsAwaken == NumThreadsWaiting)
  + if (NumThreadsAwaken == NumThreadsWaiting)
  {
  - m_SignaledValue = 0;
  - m_NumThreadsAwaken = 0;
  + m_SignaledValue.store(0);
  + m_NumThreadsAwaken.store(0);
  }
  }
  return SignaledValue;
  @@ -111,17 +112,17 @@ public:
  void Reset()
  {
  std::lock_guard<std::mutex> Lock{m_Mutex};
  - m_SignaledValue = 0;
  - m_NumThreadsAwaken = 0;
  + m_SignaledValue.store(0);
  + m_NumThreadsAwaken.store(0);
  }
  - bool IsTriggered() const { return m_SignaledValue != 0; }
  + bool IsTriggered() const { return m_SignaledValue.load() != 0; }
  private:
  std::mutex m_Mutex;
  std::condition_variable m_CondVar;
  - std::atomic_int m_SignaledValue;
  - std::atomic_int m_NumThreadsAwaken;
  + std::atomic_int m_SignaledValue{0};
  + std::atomic_int m_NumThreadsAwaken{0};
  Signal(const Signal&) = delete;
  Signal& operator=(const Signal&) = delete;
  