mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Remove timing window from RootStoppable (RIPD-1392):
RootStoppable was using two separate flags to identify that it was stopping. LoadManager was being notified when one flag was set, but checking the other flag (not yet set) to see if we were stopping. There is no strong motivation for two flags. The timing window is closed by removing one flag and moving around a chunk of code.
This commit is contained in:
@@ -161,13 +161,12 @@ RootStoppable::RootStoppable (char const* name)
|
||||
: Stoppable (name, *this)
|
||||
, m_prepared (false)
|
||||
, m_calledStop (false)
|
||||
, m_calledStopAsync (false)
|
||||
{
|
||||
}
|
||||
|
||||
bool RootStoppable::isStopping() const
|
||||
{
|
||||
return m_calledStopAsync;
|
||||
return m_calledStop;
|
||||
}
|
||||
|
||||
void RootStoppable::prepare ()
|
||||
@@ -191,25 +190,30 @@ void RootStoppable::stop (beast::Journal j)
|
||||
// Must have a prior call to start()
|
||||
assert (m_started);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_);
|
||||
if (m_calledStop)
|
||||
{
|
||||
if (auto stream = j.warn())
|
||||
stream << "Stoppable::stop called again";
|
||||
return;
|
||||
}
|
||||
m_calledStop = true;
|
||||
c_.notify_all();
|
||||
}
|
||||
stopAsync (j);
|
||||
stopRecursive (j);
|
||||
if (stopAsync (j))
|
||||
stopRecursive (j);
|
||||
}
|
||||
|
||||
void RootStoppable::stopAsync(beast::Journal j)
|
||||
bool RootStoppable::stopAsync(beast::Journal j)
|
||||
{
|
||||
if (m_calledStopAsync.exchange (true) == false)
|
||||
stopAsyncRecursive(j);
|
||||
bool alreadyCalled;
|
||||
{
|
||||
// Even though m_calledStop is atomic, we change its value under a
|
||||
// lock. This removes a small timing window that occurs if the
|
||||
// waiting thread is handling a spurious wakeup while m_calledStop
|
||||
// changes state.
|
||||
std::unique_lock<std::mutex> lock (m_);
|
||||
alreadyCalled = m_calledStop.exchange (true);
|
||||
}
|
||||
if (alreadyCalled)
|
||||
{
|
||||
if (auto stream = j.warn())
|
||||
stream << "Stoppable::stop called again";
|
||||
return false;
|
||||
}
|
||||
c_.notify_all();
|
||||
stopAsyncRecursive(j);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user