From 392d5b378ceae5e1fd7c91ca545fcf4cd105744a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 31 Mar 2013 16:16:37 +0200 Subject: bus: parse matches locally and allow registration of callbacks for them This includes code to parse and split up match strings which will also be useful to calculate bloom filter masks when the time comes. --- src/libsystemd-bus/sd-bus.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'src/libsystemd-bus/sd-bus.c') diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 047f286f0..0a263ea68 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -37,6 +37,7 @@ #include "bus-message.h" #include "bus-type.h" #include "bus-socket.h" +#include "bus-control.h" static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec); @@ -84,6 +85,8 @@ static void bus_free(sd_bus *b) { hashmap_free(b->object_callbacks); + bus_match_free(&b->match_callbacks); + free(b); } @@ -1493,6 +1496,9 @@ static int process_filter(sd_bus *bus, sd_bus_message *m) { struct filter_callback *l; int r; + assert(bus); + assert(m); + LIST_FOREACH(callbacks, l, bus->filter_callbacks) { r = l->callback(bus, 0, m, l->userdata); if (r != 0) @@ -1502,6 +1508,13 @@ static int process_filter(sd_bus *bus, sd_bus_message *m) { return 0; } +static int process_match(sd_bus *bus, sd_bus_message *m) { + assert(bus); + assert(m); + + return bus_match_run(bus, &bus->match_callbacks, 0, m); +} + static int process_builtin(sd_bus *bus, sd_bus_message *m) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; int r; @@ -1731,6 +1744,10 @@ static int process_message(sd_bus *bus, sd_bus_message *m) { if (r != 0) return r; + r = process_match(bus, m); + if (r != 0) + return r; + r = process_builtin(bus, m); if (r != 0) return r; @@ -2057,3 +2074,48 @@ int sd_bus_add_fallback(sd_bus *bus, const char *prefix, sd_message_handler_t ca int sd_bus_remove_fallback(sd_bus *bus, const char *prefix, sd_message_handler_t callback, void *userdata) { return bus_remove_object(bus, true, prefix, callback, userdata); } + +int sd_bus_add_match(sd_bus *bus, const char *match, sd_message_handler_t callback, void *userdata) { + int r = 0; + + if (!bus) + return -EINVAL; + if (!match) + return -EINVAL; + + if (bus->bus_client) { + r = bus_add_match_internal(bus, match); + if (r < 0) + return r; + } + + if (callback) { + r = bus_match_add(&bus->match_callbacks, match, callback, userdata, NULL); + if (r < 0) { + + if (bus->bus_client) + bus_remove_match_internal(bus, match); + } + } + + return r; +} + +int sd_bus_remove_match(sd_bus *bus, const char *match, sd_message_handler_t callback, void *userdata) { + int r = 0, q = 0; + + if (!bus) + return -EINVAL; + if (!match) + return -EINVAL; + + if (bus->bus_client) + r = bus_remove_match_internal(bus, match); + + if (callback) + q = bus_match_remove(&bus->match_callbacks, match, callback, userdata); + + if (r < 0) + return r; + return q; +} -- cgit v1.2.3