mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 23:58:20 +00:00
Change thread shutdown again to also work with input framework.
Seems to work, tests pass, but not really verified. Major change 1: finished flag in MsgThread was replaced by 2 flags: child_finished and main_finished. child_finished is set by child_thread and means that the processing loop is stopped immediately (no longer needed, no new input messages will be processed, if loop continues running there is an ugly delay on shutdown). (This took me a while to realize...) main_finished is set by a message that is sent back by the child to the main thread when Finished() is called (and child_finished is set). when main_finished is set, processing of output messages stops. But all messages that the child thread pushed in the queue before calling Finish() are still processed. Change 2: Logging terminate call was replaced by a smaller call that just flushes out the cache held by the main thread. This call has to be done before thread shutdown is called - otherwhise the threads will be shut down before all messages are pushed on them. (This also took me a while to realize...). Change 3: Input framework actually calls it stop methods correctly (everything was prepared, function call was missing)
This commit is contained in:
parent
bb1e2f57b9
commit
39f1b9e01f
12 changed files with 67 additions and 39 deletions
|
@ -30,6 +30,21 @@ private:
|
|||
double network_time;
|
||||
};
|
||||
|
||||
// Signals main thread that operations shut down
|
||||
class FinishedMessage : public OutputMessage<MsgThread>
|
||||
{
|
||||
public:
|
||||
FinishedMessage(MsgThread* thread)
|
||||
: OutputMessage<MsgThread>("FinishedMessage", thread)
|
||||
{ }
|
||||
|
||||
virtual bool Process() {
|
||||
Object()->main_finished = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Sends a heartbeat to the child thread.
|
||||
class HeartbeatMessage : public InputMessage<MsgThread>
|
||||
{
|
||||
|
@ -153,7 +168,8 @@ bool ReporterMessage::Process()
|
|||
MsgThread::MsgThread() : BasicThread(), queue_in(this, 0), queue_out(0, this)
|
||||
{
|
||||
cnt_sent_in = cnt_sent_out = 0;
|
||||
finished = false;
|
||||
main_finished = false;
|
||||
child_finished = false;
|
||||
failed = false;
|
||||
thread_mgr->AddMsgThread(this);
|
||||
}
|
||||
|
@ -163,7 +179,7 @@ extern int signal_val;
|
|||
|
||||
void MsgThread::OnSignalStop()
|
||||
{
|
||||
if ( finished || Killed() )
|
||||
if ( main_finished || Killed() )
|
||||
return;
|
||||
|
||||
// Signal thread to terminate.
|
||||
|
@ -180,7 +196,7 @@ void MsgThread::OnWaitForStop()
|
|||
uint64_t last_size = 0;
|
||||
uint64_t cur_size = 0;
|
||||
|
||||
while ( ! (finished || Killed() ) )
|
||||
while ( ! (main_finished || Killed() ) )
|
||||
{
|
||||
// Terminate if we get another kill signal.
|
||||
if ( signal_val == SIGTERM || signal_val == SIGINT )
|
||||
|
@ -206,6 +222,15 @@ void MsgThread::OnWaitForStop()
|
|||
}
|
||||
|
||||
queue_in.WakeUp();
|
||||
while ( HasOut() && !Killed() )
|
||||
{
|
||||
Message* msg = RetrieveOut();
|
||||
assert ( msg );
|
||||
if ( !msg->Process() )
|
||||
reporter->Error("%s failed during thread termination", msg->Name());
|
||||
|
||||
delete msg;
|
||||
}
|
||||
|
||||
usleep(1000);
|
||||
}
|
||||
|
@ -237,9 +262,8 @@ void MsgThread::HeartbeatInChild()
|
|||
|
||||
void MsgThread::Finished()
|
||||
{
|
||||
// This is thread-safe "enough", we're the only one ever writing
|
||||
// there.
|
||||
finished = true;
|
||||
child_finished = true;
|
||||
SendOut(new FinishedMessage(this));
|
||||
}
|
||||
|
||||
void MsgThread::Info(const char* msg)
|
||||
|
@ -344,7 +368,7 @@ BasicInputMessage* MsgThread::RetrieveIn()
|
|||
|
||||
void MsgThread::Run()
|
||||
{
|
||||
while ( ! (finished || Killed() ) )
|
||||
while ( ! (child_finished || Killed() ) )
|
||||
{
|
||||
BasicInputMessage* msg = RetrieveIn();
|
||||
|
||||
|
@ -368,10 +392,10 @@ void MsgThread::Run()
|
|||
}
|
||||
}
|
||||
|
||||
// In case we haven't send the finish method yet, do it now. Reading
|
||||
// In case we haven't sent the finish method yet, do it now. Reading
|
||||
// global network_time here should be fine, it isn't changing
|
||||
// anymore.
|
||||
if ( ! finished && ! Killed() )
|
||||
if ( ! child_finished && ! Killed() )
|
||||
{
|
||||
OnFinish(network_time);
|
||||
Finished();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue