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 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);
216 _public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) {
217 assert_return(slot, NULL);
222 _public_ void *sd_bus_slot_get_userdata(sd_bus_slot *slot) {
223 assert_return(slot, NULL);
225 return slot->userdata;
228 _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
231 assert_return(slot, NULL);
233 ret = slot->userdata;
234 slot->userdata = userdata;
239 _public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
240 assert_return(slot, NULL);
241 assert_return(slot->type >= 0, NULL);
243 if (slot->bus->current_slot != slot)
246 return slot->bus->current_message;