mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 07:38:19 +00:00
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:
parent
5e73949327
commit
9e494452f1
5 changed files with 49 additions and 0 deletions
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -343,6 +343,7 @@ void terminate_bro()
|
|||
|
||||
mgr.Drain();
|
||||
|
||||
notifier::registry.Terminate();
|
||||
log_mgr->Terminate();
|
||||
input_mgr->Terminate();
|
||||
thread_mgr->Terminate();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue