diff --git a/src/bus/bus.h b/src/bus/bus.h index fffc2ab9..93319d19 100644 --- a/src/bus/bus.h +++ b/src/bus/bus.h @@ -39,6 +39,7 @@ struct Bus { MatchRegistry sender_matches; PeerRegistry peers; + uint64_t n_monitors; uint64_t transaction_ids; uint64_t listener_ids; diff --git a/src/bus/driver.c b/src/bus/driver.c index 929f4fd7..1fd08805 100644 --- a/src/bus/driver.c +++ b/src/bus/driver.c @@ -320,6 +320,9 @@ static int driver_monitor(Bus *bus, Peer *sender, Message *message) { NameOwnership *ownership; int r; + if (!bus->n_monitors) + return 0; + filter.type = message->metadata.header.type; filter.sender = sender ? sender->id : ADDRESS_ID_INVALID; filter.interface = message->metadata.fields.interface; @@ -1789,6 +1792,8 @@ int driver_goodbye(Peer *peer, bool silent) { return error_trace(r); } peer_unregister(peer); + } else if (peer_is_monitor(peer)) { + peer_stop_monitor(peer); } c_list_for_each_entry_safe(rule, rule_safe, &peer->name_owner_changed_matches.rule_list, registry_link) diff --git a/src/bus/peer.c b/src/bus/peer.c index 666f160a..cdd7aaa7 100644 --- a/src/bus/peer.c +++ b/src/bus/peer.c @@ -575,10 +575,20 @@ int peer_become_monitor(Peer *peer, MatchOwner *owned_matches) { return poison; peer->monitor = true; + ++peer->bus->n_monitors; return 0; } +void peer_stop_monitor(Peer *peer) { + assert(!peer->registered); + assert(peer->monitor); + assert(c_rbtree_is_empty(&peer->owned_matches.rule_tree)); + + peer->monitor = false; + --peer->bus->n_monitors; +} + void peer_flush_matches(Peer *peer) { CRBNode *node; diff --git a/src/bus/peer.h b/src/bus/peer.h index 10709003..d660f95a 100644 --- a/src/bus/peer.h +++ b/src/bus/peer.h @@ -119,6 +119,7 @@ void peer_release_name_ownership(Peer *peer, NameOwnership *ownership, NameChang int peer_add_match(Peer *peer, const char *rule_string); int peer_remove_match(Peer *peer, const char *rule_string); int peer_become_monitor(Peer *peer, MatchOwner *owner); +void peer_stop_monitor(Peer *peer); void peer_flush_matches(Peer *peer); int peer_queue_call(PolicySnapshot *sender_policy, NameSet *sender_names, MatchRegistry *sender_matches, ReplyOwner *sender_replies, User *sender_user, uint64_t sender_id, Peer *receiver, Message *message);