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/>.
23 #include "bus-control.h"
24 #include "bus-objects.h"
27 sd_bus_slot *bus_slot_allocate(
38 slot = malloc0(offsetof(sd_bus_slot, reply_callback) + extra);
45 slot->floating = floating;
46 slot->userdata = userdata;
51 LIST_PREPEND(slots, bus->slots, slot);
56 _public_ sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot) {
57 assert_return(slot, NULL);
59 assert(slot->n_ref > 0);
65 void bus_slot_disconnect(sd_bus_slot *slot) {
75 case BUS_REPLY_CALLBACK:
77 if (slot->reply_callback.cookie != 0)
78 ordered_hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
80 if (slot->reply_callback.timeout != 0)
81 prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
85 case BUS_FILTER_CALLBACK:
86 slot->bus->filter_callbacks_modified = true;
87 LIST_REMOVE(callbacks, slot->bus->filter_callbacks, &slot->filter_callback);
90 case BUS_MATCH_CALLBACK:
92 if (slot->bus->bus_client)
93 bus_remove_match_internal(slot->bus, slot->match_callback.match_string, slot->match_callback.cookie);
95 slot->bus->match_callbacks_modified = true;
96 bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback);
98 free(slot->match_callback.match_string);
102 case BUS_NODE_CALLBACK:
104 if (slot->node_callback.node) {
105 LIST_REMOVE(callbacks, slot->node_callback.node->callbacks, &slot->node_callback);
106 slot->bus->nodes_modified = true;
108 bus_node_gc(slot->bus, slot->node_callback.node);
113 case BUS_NODE_ENUMERATOR:
115 if (slot->node_enumerator.node) {
116 LIST_REMOVE(enumerators, slot->node_enumerator.node->enumerators, &slot->node_enumerator);
117 slot->bus->nodes_modified = true;
119 bus_node_gc(slot->bus, slot->node_enumerator.node);
124 case BUS_NODE_OBJECT_MANAGER:
126 if (slot->node_object_manager.node) {
127 LIST_REMOVE(object_managers, slot->node_object_manager.node->object_managers, &slot->node_object_manager);
128 slot->bus->nodes_modified = true;
130 bus_node_gc(slot->bus, slot->node_object_manager.node);
135 case BUS_NODE_VTABLE:
137 if (slot->node_vtable.node && slot->node_vtable.interface && slot->node_vtable.vtable) {
138 const sd_bus_vtable *v;
140 for (v = slot->node_vtable.vtable; v->type != _SD_BUS_VTABLE_END; v++) {
141 struct vtable_member *x = NULL;
145 case _SD_BUS_VTABLE_METHOD: {
146 struct vtable_member key;
148 key.path = slot->node_vtable.node->path;
149 key.interface = slot->node_vtable.interface;
150 key.member = v->x.method.member;
152 x = hashmap_remove(slot->bus->vtable_methods, &key);
156 case _SD_BUS_VTABLE_PROPERTY:
157 case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
158 struct vtable_member key;
160 key.path = slot->node_vtable.node->path;
161 key.interface = slot->node_vtable.interface;
162 key.member = v->x.method.member;
165 x = hashmap_remove(slot->bus->vtable_properties, &key);
173 free(slot->node_vtable.interface);
175 if (slot->node_vtable.node) {
176 LIST_REMOVE(vtables, slot->node_vtable.node->vtables, &slot->node_vtable);
177 slot->bus->nodes_modified = true;
179 bus_node_gc(slot->bus, slot->node_vtable.node);
185 assert_not_reached("Wut? Unknown slot type?");
190 slot->type = _BUS_SLOT_INVALID;
192 LIST_REMOVE(slots, bus->slots, slot);
198 _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
203 assert(slot->n_ref > 0);
205 if (slot->n_ref > 1) {
210 bus_slot_disconnect(slot);
211 free(slot->description);
217 _public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) {
218 assert_return(slot, NULL);
223 _public_ void *sd_bus_slot_get_userdata(sd_bus_slot *slot) {
224 assert_return(slot, NULL);
226 return slot->userdata;
229 _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
232 assert_return(slot, NULL);
234 ret = slot->userdata;
235 slot->userdata = userdata;
240 _public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
241 assert_return(slot, NULL);
242 assert_return(slot->type >= 0, NULL);
244 if (slot->bus->current_slot != slot)
247 return slot->bus->current_message;
250 _public_ sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot) {
251 assert_return(slot, NULL);
252 assert_return(slot->type >= 0, NULL);
254 if (slot->bus->current_slot != slot)
257 return slot->bus->current_handler;
260 _public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) {
261 assert_return(slot, NULL);
262 assert_return(slot->type >= 0, NULL);
264 if (slot->bus->current_slot != slot)
267 return slot->bus->current_userdata;
270 _public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description) {
271 assert_return(slot, -EINVAL);
273 return free_and_strdup(&slot->description, description);
276 _public_ int sd_bus_slot_get_description(sd_bus_slot *slot, char **description) {
277 assert_return(slot, -EINVAL);
278 assert_return(description, -EINVAL);
279 assert_return(slot->description, -ENXIO);
281 *description = slot->description;