mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Refactor Stoppable:
The Stoppable interface aids in the enforcement of invariants needed to successful start and stop a multi-threaded application composed of classes that depend on each other in complex ways. * Test written to confirm the current behavior. * Comments updated to reflect the current behavior. * Public API reduced to what is currently in use. * Protected data members made private. * volatile bool members changed to std::atomic<bool>. * std::atomic<int> members changed to std::atomic<bool>. * Name storage uses std::string
This commit is contained in:
committed by
Vinnie Falco
parent
68fe1a7c8f
commit
eb64a4387d
@@ -25,7 +25,7 @@ Stoppable::Stoppable (char const* name, RootStoppable& root)
|
||||
: m_name (name)
|
||||
, m_root (root)
|
||||
, m_child (this)
|
||||
, m_started (0)
|
||||
, m_started (false)
|
||||
, m_stopped (false)
|
||||
, m_childrenStopped (false)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ Stoppable::Stoppable (char const* name, Stoppable& parent)
|
||||
: m_name (name)
|
||||
, m_root (parent.m_root)
|
||||
, m_child (this)
|
||||
, m_started (0)
|
||||
, m_started (false)
|
||||
, m_stopped (false)
|
||||
, m_childrenStopped (false)
|
||||
{
|
||||
@@ -48,7 +48,7 @@ Stoppable::Stoppable (char const* name, Stoppable& parent)
|
||||
Stoppable::~Stoppable ()
|
||||
{
|
||||
// Children must be stopped.
|
||||
bassert (m_started.load () == 0 || m_childrenStopped);
|
||||
bassert (!m_started || m_childrenStopped);
|
||||
}
|
||||
|
||||
bool Stoppable::isStopping() const
|
||||
@@ -124,7 +124,6 @@ void Stoppable::stopRecursive (Journal journal)
|
||||
|
||||
// if we get here then all children have stopped
|
||||
//
|
||||
memoryBarrier ();
|
||||
m_childrenStopped = true;
|
||||
onChildrenStopped ();
|
||||
|
||||
@@ -145,39 +144,39 @@ void Stoppable::stopRecursive (Journal journal)
|
||||
|
||||
RootStoppable::RootStoppable (char const* name)
|
||||
: Stoppable (name, *this)
|
||||
, m_prepared (0)
|
||||
, m_calledStop (0)
|
||||
, m_calledStopAsync (0)
|
||||
, m_prepared (false)
|
||||
, m_calledStop (false)
|
||||
, m_calledStopAsync (false)
|
||||
{
|
||||
}
|
||||
|
||||
bool RootStoppable::isStopping() const
|
||||
{
|
||||
return m_calledStopAsync.load () != 0;
|
||||
return m_calledStopAsync;
|
||||
}
|
||||
|
||||
void RootStoppable::prepare ()
|
||||
{
|
||||
if (m_prepared.exchange (1) == 0)
|
||||
if (m_prepared.exchange (true) == false)
|
||||
prepareRecursive ();
|
||||
}
|
||||
|
||||
void RootStoppable::start ()
|
||||
{
|
||||
// Courtesy call to prepare.
|
||||
if (m_prepared.exchange (1) == 0)
|
||||
if (m_prepared.exchange (true) == false)
|
||||
prepareRecursive ();
|
||||
|
||||
if (m_started.exchange (1) == 0)
|
||||
if (m_started.exchange (true) == false)
|
||||
startRecursive ();
|
||||
}
|
||||
|
||||
void RootStoppable::stop (Journal journal)
|
||||
{
|
||||
// Must have a prior call to start()
|
||||
bassert (m_started.load () != 0);
|
||||
bassert (m_started);
|
||||
|
||||
if (m_calledStop.exchange (1) == 1)
|
||||
if (m_calledStop.exchange (true) == true)
|
||||
{
|
||||
journal.warning << "Stoppable::stop called again";
|
||||
return;
|
||||
@@ -189,7 +188,7 @@ void RootStoppable::stop (Journal journal)
|
||||
|
||||
void RootStoppable::stopAsync ()
|
||||
{
|
||||
if (m_calledStopAsync.exchange (1) == 0)
|
||||
if (m_calledStopAsync.exchange (true) == false)
|
||||
stopAsyncRecursive ();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user