diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-04-05 03:55:58 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-04-05 03:55:58 +0200 |
commit | 7286037fd438e93137571fa68a741cc894d8e549 (patch) | |
tree | f34cbc20ec29ca10e1d866859c0f0289ed14fb72 /src/libsystemd-bus/bus-match.c | |
parent | 6807947e56d7d1b40ec4e984a5f631fb6d5a6834 (diff) |
bus: properly detect and handle if a callback is installed/removed from within a callback
Diffstat (limited to 'src/libsystemd-bus/bus-match.c')
-rw-r--r-- | src/libsystemd-bus/bus-match.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c index 972ac8e00e..fed25c1a2a 100644 --- a/src/libsystemd-bus/bus-match.c +++ b/src/libsystemd-bus/bus-match.c @@ -212,6 +212,9 @@ int bus_match_run( if (!node) return 0; + if (bus && bus->match_callbacks_modified) + return 0; + /* Not these special semantics: when traversing the tree we * usually let bus_match_run() when called for a node * recursively invoke bus_match_run(). There's are two @@ -241,6 +244,13 @@ int bus_match_run( case BUS_MATCH_LEAF: + if (bus) { + if (node->leaf.last_iteration == bus->iteration_counter) + return 0; + + node->leaf.last_iteration = bus->iteration_counter; + } + /* Run the callback. And then invoke siblings. */ assert(node->leaf.callback); r = node->leaf.callback(bus, ret, m, node->leaf.userdata); @@ -323,6 +333,9 @@ int bus_match_run( } } + if (bus && bus->match_callbacks_modified) + return 0; + /* And now, let's invoke our siblings */ return bus_match_run(bus, node->next, ret, m); } |