X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-internal.h;h=1726b618418a45f76f6fc976478340e5816bdc6b;hp=147a83c0452dde0c67d7d5b814a5a6d597349c8b;hb=40ca29a1370379d43e44c0ed425eecc7218dcbca;hpb=c78196699d3d805b2237896a1d2b8efeec6068d0 diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 147a83c04..1726b6184 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -54,14 +54,63 @@ struct filter_callback { LIST_FIELDS(struct filter_callback, callbacks); }; -struct object_callback { +struct node { + char *path; + struct node *parent; + LIST_HEAD(struct node, child); + LIST_FIELDS(struct node, siblings); + + LIST_HEAD(struct node_callback, callbacks); + LIST_HEAD(struct node_vtable, vtables); + LIST_HEAD(struct node_enumerator, enumerators); + + bool object_manager; +}; + +struct node_callback { + struct node *node; + + bool is_fallback; sd_bus_message_handler_t callback; void *userdata; - char *path; + unsigned last_iteration; + + LIST_FIELDS(struct node_callback, callbacks); +}; + +struct node_enumerator { + struct node *node; + + sd_bus_node_enumerator_t callback; + void *userdata; + + unsigned last_iteration; + + LIST_FIELDS(struct node_enumerator, enumerators); +}; + +struct node_vtable { + struct node *node; + + char *interface; bool is_fallback; + const sd_bus_vtable *vtable; + void *userdata; + sd_bus_object_find_t find; unsigned last_iteration; + + LIST_FIELDS(struct node_vtable, vtables); +}; + +struct vtable_member { + const char *path; + const char *interface; + const char *member; + struct node_vtable *parent; + unsigned last_iteration; + const sd_bus_vtable *vtable; }; enum bus_state { @@ -109,7 +158,9 @@ struct sd_bus { bool processing:1; bool match_callbacks_modified:1; bool filter_callbacks_modified:1; - bool object_callbacks_modified:1; + bool nodes_modified:1; + + int use_memfd; void *rbuffer; size_t rbuffer_size; @@ -129,7 +180,12 @@ struct sd_bus { Prioq *reply_callbacks_prioq; Hashmap *reply_callbacks; LIST_HEAD(struct filter_callback, filter_callbacks); - Hashmap *object_callbacks; + + Hashmap *nodes; + + + Hashmap *vtable_methods; + Hashmap *vtable_properties; union { struct sockaddr sa; @@ -184,14 +240,12 @@ struct sd_bus { uint64_t hello_flags; uint64_t match_cookie; -}; -static inline void bus_unrefp(sd_bus **b) { - sd_bus_unref(*b); -} - -#define _cleanup_bus_unref_ __attribute__((cleanup(bus_unrefp))) -#define _cleanup_bus_error_free_ __attribute__((cleanup(sd_bus_error_free))) + sd_event_source *input_io_event_source; + sd_event_source *output_io_event_source; + sd_event_source *time_event_source; + sd_event *event; +}; #define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC)) @@ -211,10 +265,11 @@ static inline void bus_unrefp(sd_bus **b) { #define BUS_EXEC_ARGV_MAX 256 -bool object_path_is_valid(const char *p); bool interface_name_is_valid(const char *p); bool service_name_is_valid(const char *p); bool member_name_is_valid(const char *p); +bool object_path_is_valid(const char *p); +char *object_path_startswith(const char *a, const char *b); bool namespace_complex_pattern(const char *pattern, const char *value); bool path_complex_pattern(const char *pattern, const char *value); @@ -232,3 +287,14 @@ int bus_start_running(sd_bus *bus); int bus_next_address(sd_bus *bus); bool bus_pid_changed(sd_bus *bus); + +#define OBJECT_PATH_FOREACH_PREFIX(prefix, path) \ + for (char *_slash = ({ strcpy((prefix), (path)); streq((prefix), "/") ? NULL : strrchr((prefix), '/'); }) ; \ + _slash && !(_slash[(_slash) == (prefix)] = 0); \ + _slash = streq((prefix), "/") ? NULL : strrchr((prefix), '/')) + +/* If we are invoking callbacks of a bus object, ensure unreffing the + * bus from the callback doesn't destroy the object we are working + * on */ +#define BUS_DONT_DESTROY(bus) \ + _cleanup_bus_unref_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus)