static bool bus_match_node_maybe_free(struct bus_match_node *node) {
assert(node);
+ if (node->type == BUS_MATCH_ROOT)
+ return false;
+
if (node->child)
return false;
case BUS_MATCH_LEAF:
if (bus) {
- if (node->leaf.last_iteration == bus->iteration_counter)
+ if (node->leaf.callback->last_iteration == bus->iteration_counter)
return 0;
- node->leaf.last_iteration = bus->iteration_counter;
+ node->leaf.callback->last_iteration = bus->iteration_counter;
}
r = sd_bus_message_rewind(m, true);
return r;
/* Run the callback. And then invoke siblings. */
- if (node->leaf.callback) {
+ if (node->leaf.callback->callback) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+ sd_bus_slot *slot;
+
+ slot = container_of(node->leaf.callback, sd_bus_slot, match_callback);
+ if (bus)
+ bus->current_slot = sd_bus_slot_ref(slot);
+ r = node->leaf.callback->callback(bus, m, slot->userdata, &error_buffer);
+ if (bus)
+ bus->current_slot = sd_bus_slot_unref(slot);
- r = node->leaf.callback(bus, m, node->leaf.userdata, &error_buffer);
r = bus_maybe_reply_error(m, r, &error_buffer);
if (r != 0)
return r;
+
+ if (bus && bus->match_callbacks_modified)
+ return 0;
}
return bus_match_run(bus, node->next, m);
static int bus_match_add_leaf(
struct bus_match_node *where,
- sd_bus_message_handler_t callback,
- void *userdata,
- uint64_t cookie,
- struct bus_match_node **ret) {
+ struct match_callback *callback) {
struct bus_match_node *n;
assert(where);
assert(where->type == BUS_MATCH_ROOT || where->type == BUS_MATCH_VALUE);
- assert(ret);
+ assert(callback);
n = new0(struct bus_match_node, 1);
if (!n)
n->next = where->child;
if (n->next)
n->next->prev = n;
+
n->leaf.callback = callback;
- n->leaf.userdata = userdata;
- n->leaf.cookie = cookie;
+ callback->match_node = n;
where->child = n;
- *ret = n;
return 1;
}
assert(ret);
for (c = where->child; c; c = c->next) {
+ sd_bus_slot *s;
+
+ s = container_of(c->leaf.callback, sd_bus_slot, match_callback);
+
if (c->type == BUS_MATCH_LEAF &&
- c->leaf.callback == callback &&
- c->leaf.userdata == userdata) {
+ c->leaf.callback->callback == callback &&
+ s->userdata == userdata) {
*ret = c;
return 1;
}
value = NULL;
- if (q[1] == 0)
+ if (q[quoted] == 0)
break;
if (q[quoted] != ',') {
struct bus_match_node *root,
struct bus_match_component *components,
unsigned n_components,
- sd_bus_message_handler_t callback,
- void *userdata,
- uint64_t cookie,
- struct bus_match_node **ret) {
+ struct match_callback *callback) {
unsigned i;
struct bus_match_node *n;
int r;
assert(root);
+ assert(callback);
n = root;
for (i = 0; i < n_components; i++) {
return r;
}
- r = bus_match_add_leaf(n, callback, userdata, cookie, &n);
- if (r < 0)
- return r;
+ return bus_match_add_leaf(n, callback);
+}
- if (ret)
- *ret = n;
+int bus_match_remove(
+ struct bus_match_node *root,
+ struct match_callback *callback) {
- return 0;
+ struct bus_match_node *node, *pp;
+
+ assert(root);
+ assert(callback);
+
+ node = callback->match_node;
+ if (!node)
+ return 0;
+
+ assert(node->type == BUS_MATCH_LEAF);
+
+ callback->match_node = NULL;
+
+ /* Free the leaf */
+ pp = node->parent;
+ bus_match_node_free(node);
+
+ /* Prune the tree above */
+ while (pp) {
+ node = pp;
+ pp = node->parent;
+
+ if (!bus_match_node_maybe_free(node))
+ break;
+ }
+
+ return 1;
}
-int bus_match_remove(
+int bus_match_find(
struct bus_match_node *root,
struct bus_match_component *components,
unsigned n_components,
sd_bus_message_handler_t callback,
void *userdata,
- uint64_t *cookie) {
+ struct match_callback **ret) {
- unsigned i;
struct bus_match_node *n, **gc;
+ unsigned i;
int r;
assert(root);
+ assert(ret);
gc = newa(struct bus_match_node*, n_components);
if (r <= 0)
return r;
- if (cookie)
- *cookie = n->leaf.cookie;
-
- /* Free the leaf */
- bus_match_node_free(n);
-
- /* Prune the tree above */
- for (i = n_components; i > 0; i --) {
- struct bus_match_node *p = gc[i-1]->parent;
-
- if (!bus_match_node_maybe_free(gc[i-1]))
- break;
-
- if (!bus_match_node_maybe_free(p))
- break;
- }
-
- return r;
+ *ret = n->leaf.callback;
+ return 1;
}
void bus_match_free(struct bus_match_node *node) {
} else if (node->type == BUS_MATCH_ROOT)
puts(" root");
else if (node->type == BUS_MATCH_LEAF)
- printf(" %p/%p\n", node->leaf.callback, node->leaf.userdata);
+ printf(" %p/%p\n", node->leaf.callback->callback, container_of(node->leaf.callback, sd_bus_slot, match_callback)->userdata);
else
putchar('\n');