Changing semantics of thread stop methods.

PrepareStop() is now SignalStop() and just signals a thread that it
should terminate. After that's called, WaitForStop() (formerly Stop())
wait for it to actually finish processing.

When stopping writers during operation, we now no longer wait for them
to finish.
This commit is contained in:
Robin Sommer 2013-03-15 17:54:20 -07:00
parent 38e1dc9ca4
commit d11bd56b5d
6 changed files with 45 additions and 44 deletions

View file

@ -141,8 +141,7 @@ void WriterFrontend::Stop()
if ( backend ) if ( backend )
{ {
backend->PrepareStop(); backend->SignalStop();
backend->Stop();
backend = 0; // Thread manager will clean it up once it finishes. backend = 0; // Thread manager will clean it up once it finishes.
} }
} }

View file

@ -117,20 +117,7 @@ void BasicThread::Start()
OnStart(); OnStart();
} }
void BasicThread::PrepareStop() void BasicThread::SignalStop()
{
if ( ! started )
return;
if ( terminating )
return;
DBG_LOG(DBG_THREADING, "Preparing thread %s to terminate ...", name);
OnPrepareStop();
}
void BasicThread::Stop()
{ {
if ( ! started ) if ( ! started )
return; return;
@ -140,7 +127,20 @@ void BasicThread::Stop()
DBG_LOG(DBG_THREADING, "Signaling thread %s to terminate ...", name); DBG_LOG(DBG_THREADING, "Signaling thread %s to terminate ...", name);
OnStop(); OnSignalStop();
}
void BasicThread::WaitForStop()
{
if ( ! started )
return;
if ( terminating )
return;
DBG_LOG(DBG_THREADING, "Waiting for thread %s to terminate ...", name);
OnWaitForStop();
terminating = true; terminating = true;
} }

View file

@ -71,32 +71,33 @@ public:
void Start(); void Start();
/** /**
* Signals the thread to prepare for stopping. This must be called * Signals the thread to prepare for stopping, but doesn't block to
* before Stop() and allows the thread to trigger shutting down * wait for that to happen. Use WaitForStop() for that.
* without yet blocking for doing so.
* *
* The method lets Terminating() now return true, it does however not
* force the thread to terminate. It's up to the Run() method to to
* query Terminating() and exit eventually.
*
* Calling this method has no effect if Start() hasn't been executed * Calling this method has no effect if Start() hasn't been executed
* yet. * yet.
* *
* Only Bro's main thread must call this method. * Only Bro's main thread must call this method.
*/ */
void PrepareStop(); void SignalStop();
/** /**
* Signals the thread to stop. The method lets Terminating() now * Waits until a thread has stopped after receiving SignalStop().
* return true. It does however not force the thread to terminate.
* It's up to the Run() method to to query Terminating() and exit
* eventually.
* *
* Calling this method has no effect if Start() hasn't been executed * Calling this method has no effect if Start() hasn't been executed
* yet. * yet. If this is executed without calling SignalStop() first,
* results are undefined.
* *
* Only Bro's main thread must call this method. * Only Bro's main thread must call this method.
*/ */
void Stop(); void WaitForStop();
/** /**
* Returns true if Stop() has been called. * Returns true if WaitForStop() has been called and finished.
* *
* This method is safe to call from any thread. * This method is safe to call from any thread.
*/ */
@ -145,18 +146,19 @@ protected:
virtual void OnStart() {} virtual void OnStart() {}
/** /**
* Executed with PrepareStop() (and before OnStop()). This is a hook * Executed with SignalStop(). This is a hook into preparing the
* into preparing the thread for stopping. It will be called from * thread for stopping. It will be called from Bro's main thread
* Bro's main thread before the thread has been signaled to stop. * before the thread has been signaled to stop.
*/ */
virtual void OnPrepareStop() {} virtual void OnSignalStop() {}
/** /**
* Executed with Stop() (and after OnPrepareStop()). This is a hook * Executed with WaitForStop(). This is a hook into waiting for the
* into stopping the thread. It will be called from Bro's main thread * thread to stop. It must be overridden by derived classes and only
* after the thread has been signaled to stop. * return once the thread has indeed finished processing. The method
* will be called from Bro's main thread.
*/ */
virtual void OnStop() {} virtual void OnWaitForStop() = 0;
/** /**
* Executed with Kill(). This is a hook into killing the thread. * Executed with Kill(). This is a hook into killing the thread.

View file

@ -32,10 +32,10 @@ void Manager::Terminate()
// Signal all to stop. // Signal all to stop.
for ( all_thread_list::iterator i = all_threads.begin(); i != all_threads.end(); i++ ) for ( all_thread_list::iterator i = all_threads.begin(); i != all_threads.end(); i++ )
(*i)->PrepareStop(); (*i)->SignalStop();
for ( all_thread_list::iterator i = all_threads.begin(); i != all_threads.end(); i++ ) for ( all_thread_list::iterator i = all_threads.begin(); i != all_threads.end(); i++ )
(*i)->Stop(); (*i)->WaitForStop();
// Then join them all. // Then join them all.
for ( all_thread_list::iterator i = all_threads.begin(); i != all_threads.end(); i++ ) for ( all_thread_list::iterator i = all_threads.begin(); i != all_threads.end(); i++ )
@ -141,7 +141,7 @@ void Manager::Process()
else else
{ {
reporter->Error("%s failed, terminating thread", msg->Name()); reporter->Error("%s failed, terminating thread", msg->Name());
t->Stop(); t->SignalStop();
} }
delete msg; delete msg;

View file

@ -161,16 +161,16 @@ MsgThread::MsgThread() : BasicThread(), queue_in(this, 0), queue_out(0, this)
// Set by Bro's main signal handler. // Set by Bro's main signal handler.
extern int signal_val; extern int signal_val;
void MsgThread::OnPrepareStop() void MsgThread::OnSignalStop()
{ {
if ( finished || Killed() ) if ( finished || Killed() )
return; return;
// Signal thread to terminate and wait until it has acknowledged. // Signal thread to terminate.
SendIn(new FinishMessage(this, network_time), true); SendIn(new FinishMessage(this, network_time), true);
} }
void MsgThread::OnStop() void MsgThread::OnWaitForStop()
{ {
int signal_count = 0; int signal_count = 0;
int old_signal_val = signal_val; int old_signal_val = signal_val;

View file

@ -228,8 +228,8 @@ protected:
* *
*/ */
virtual void Run(); virtual void Run();
virtual void OnStop(); virtual void OnWaitForStop();
virtual void OnPrepareStop(); virtual void OnSignalStop();
virtual void OnKill(); virtual void OnKill();
private: private: