Clean up triggers awaiting global state modification at shutdown

Otherwise they can be reported as memory leaks since no more global
state modifications will take place to notify the trigger to clean
itself up.
This commit is contained in:
Jon Siwek 2019-12-30 14:04:19 -08:00
parent 5e73949327
commit 9e494452f1
5 changed files with 49 additions and 0 deletions

View file

@ -65,6 +65,17 @@ void notifier::Registry::Modified(Modifiable* m)
i->second->Modified(m);
}
void notifier::Registry::Terminate()
{
std::set<Receiver*> receivers;
for ( auto& r : registrations )
receivers.emplace(r.second);
for ( auto& r : receivers )
r->Terminate();
}
notifier::Modifiable::~Modifiable()
{
if ( num_receivers )

View file

@ -30,6 +30,12 @@ public:
* @param m object that was modified
*/
virtual void Modified(Modifiable* m) = 0;
/**
* Callback executed when notification registry is terminating and
* no further modifications can possibly occur.
*/
virtual void Terminate() { }
};
/** Singleton class tracking all notification requests globally. */
@ -69,6 +75,12 @@ public:
*/
void Unregister(Modifiable* m);
/**
* Notifies all receivers that no further modifications will occur
* as the registry is shutting down.
*/
void Terminate();
private:
friend class Modifiable;

View file

@ -171,6 +171,27 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
Unref(this);
}
void Trigger::Terminate()
{
if ( is_return )
{
auto parent = frame->GetTrigger();
if ( ! parent->Disabled() )
{
// If the trigger was already disabled due to interpreter
// exception, an Unref already happened at that point.
parent->Disable();
Unref(parent);
}
frame->ClearTrigger();
}
Disable();
Unref(this);
}
Trigger::~Trigger()
{
DBG_LOG(DBG_NOTIFIERS, "%s: deleting", Name());

View file

@ -62,6 +62,10 @@ public:
// later to avoid race conditions.
void Modified(notifier::Modifiable* m) override
{ QueueTrigger(this); }
// Overridden from notifer::Receiver. If we're still waiting
// on an ID/Val to be modified at termination time, we can't hope
// for any further progress to be made, so just Unref ourselves.
void Terminate() override;
const char* Name() const;

View file

@ -343,6 +343,7 @@ void terminate_bro()
mgr.Drain();
notifier::registry.Terminate();
log_mgr->Terminate();
input_mgr->Terminate();
thread_mgr->Terminate();