summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus/bus-match.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-04-05 03:55:58 +0200
committerLennart Poettering <lennart@poettering.net>2013-04-05 03:55:58 +0200
commit7286037fd438e93137571fa68a741cc894d8e549 (patch)
treef34cbc20ec29ca10e1d866859c0f0289ed14fb72 /src/libsystemd-bus/bus-match.c
parent6807947e56d7d1b40ec4e984a5f631fb6d5a6834 (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.c13
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);
}