1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include "alloc-util.h"
25 #include "bus-control.h"
26 #include "bus-objects.h"
28 #include "string-util.h"
30 sd_bus_slot *bus_slot_allocate(
41 slot = malloc0(offsetof(sd_bus_slot, reply_callback) + extra);
48 slot->floating = floating;
49 slot->userdata = userdata;
54 LIST_PREPEND(slots, bus->slots, slot);
59 _public_ sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot) {
64 assert(slot->n_ref > 0);
70 void bus_slot_disconnect(sd_bus_slot *slot) {
80 case BUS_REPLY_CALLBACK:
82 if (slot->reply_callback.cookie != 0)
83 ordered_hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
85 if (slot->reply_callback.timeout != 0)
86 prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
90 case BUS_FILTER_CALLBACK:
91 slot->bus->filter_callbacks_modified = true;
92 LIST_REMOVE(callbacks, slot->bus->filter_callbacks, &slot->filter_callback);
95 case BUS_MATCH_CALLBACK:
97 if (slot->match_added)
98 bus_remove_match_internal(slot->bus, slot->match_callback.match_string, slot->match_callback.cookie);
100 slot->bus->match_callbacks_modified = true;
101 bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback);
103 free(slot->match_callback.match_string);
107 case BUS_NODE_CALLBACK:
109 if (slot->node_callback.node) {
110 LIST_REMOVE(callbacks, slot->node_callback.node->callbacks, &slot->node_callback);
111 slot->bus->nodes_modified = true;
113 bus_node_gc(slot->bus, slot->node_callback.node);
118 case BUS_NODE_ENUMERATOR:
120 if (slot->node_enumerator.node) {
121 LIST_REMOVE(enumerators, slot->node_enumerator.node->enumerators, &slot->node_enumerator);
122 slot->bus->nodes_modified = true;
124 bus_node_gc(slot->bus, slot->node_enumerator.node);
129 case BUS_NODE_OBJECT_MANAGER:
131 if (slot->node_object_manager.node) {
132 LIST_REMOVE(object_managers, slot->node_object_manager.node->object_managers, &slot->node_object_manager);
133 slot->bus->nodes_modified = true;
135 bus_node_gc(slot->bus, slot->node_object_manager.node);
140 case BUS_NODE_VTABLE:
142 if (slot->node_vtable.node && slot->node_vtable.interface && slot->node_vtable.vtable) {
143 const sd_bus_vtable *v;
145 for (v = slot->node_vtable.vtable; v->type != _SD_BUS_VTABLE_END; v++) {
146 struct vtable_member *x = NULL;
150 case _SD_BUS_VTABLE_METHOD: {
151 struct vtable_member key;
153 key.path = slot->node_vtable.node->path;
154 key.interface = slot->node_vtable.interface;
155 key.member = v->x.method.member;
157 x = hashmap_remove(slot->bus->vtable_methods, &key);
161 case _SD_BUS_VTABLE_PROPERTY:
162 case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
163 struct vtable_member key;
165 key.path = slot->node_vtable.node->path;
166 key.interface = slot->node_vtable.interface;
167 key.member = v->x.method.member;
170 x = hashmap_remove(slot->bus->vtable_properties, &key);
178 free(slot->node_vtable.interface);
180 if (slot->node_vtable.node) {
181 LIST_REMOVE(vtables, slot->node_vtable.node->vtables, &slot->node_vtable);
182 slot->bus->nodes_modified = true;
184 bus_node_gc(slot->bus, slot->node_vtable.node);
190 assert_not_reached("Wut? Unknown slot type?");
195 slot->type = _BUS_SLOT_INVALID;
197 LIST_REMOVE(slots, bus->slots, slot);
203 _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
208 assert(slot->n_ref > 0);
210 if (slot->n_ref > 1) {
215 bus_slot_disconnect(slot);
216 free(slot->description);
222 #if 0 /// UNNEEDED by elogind
223 _public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) {
224 assert_return(slot, NULL);
229 _public_ void *sd_bus_slot_get_userdata(sd_bus_slot *slot) {
230 assert_return(slot, NULL);
232 return slot->userdata;
235 _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
238 assert_return(slot, NULL);
240 ret = slot->userdata;
241 slot->userdata = userdata;
246 _public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
247 assert_return(slot, NULL);
248 assert_return(slot->type >= 0, NULL);
250 if (slot->bus->current_slot != slot)
253 return slot->bus->current_message;
256 _public_ sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot) {
257 assert_return(slot, NULL);
258 assert_return(slot->type >= 0, NULL);
260 if (slot->bus->current_slot != slot)
263 return slot->bus->current_handler;
266 _public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) {
267 assert_return(slot, NULL);
268 assert_return(slot->type >= 0, NULL);
270 if (slot->bus->current_slot != slot)
273 return slot->bus->current_userdata;
276 _public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description) {
277 assert_return(slot, -EINVAL);
279 return free_and_strdup(&slot->description, description);
282 _public_ int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description) {
283 assert_return(slot, -EINVAL);
284 assert_return(description, -EINVAL);
285 assert_return(slot->description, -ENXIO);
287 *description = slot->description;