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) {
72 case _BUS_SLOT_DISCONNECTED:
73 /* Already disconnected... */
76 case BUS_REPLY_CALLBACK:
78 if (slot->reply_callback.cookie != 0)
79 hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
81 if (slot->reply_callback.timeout != 0)
82 prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
86 case BUS_FILTER_CALLBACK:
87 slot->bus->filter_callbacks_modified = true;
88 LIST_REMOVE(callbacks, slot->bus->filter_callbacks, &slot->filter_callback);
91 case BUS_MATCH_CALLBACK:
93 if (slot->bus->bus_client)
94 bus_remove_match_internal(slot->bus, slot->match_callback.match_string, slot->match_callback.cookie);
96 slot->bus->match_callbacks_modified = true;
97 bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback);
99 free(slot->match_callback.match_string);
103 case BUS_NODE_CALLBACK:
105 if (slot->node_callback.node) {
106 LIST_REMOVE(callbacks, slot->node_callback.node->callbacks, &slot->node_callback);
107 slot->bus->nodes_modified = true;
109 bus_node_gc(slot->bus, slot->node_callback.node);
114 case BUS_NODE_ENUMERATOR:
116 if (slot->node_enumerator.node) {
117 LIST_REMOVE(enumerators, slot->node_enumerator.node->enumerators, &slot->node_enumerator);
118 slot->bus->nodes_modified = true;
120 bus_node_gc(slot->bus, slot->node_enumerator.node);
125 case BUS_NODE_OBJECT_MANAGER:
127 if (slot->node_object_manager.node) {
128 LIST_REMOVE(object_managers, slot->node_object_manager.node->object_managers, &slot->node_object_manager);
129 slot->bus->nodes_modified = true;
131 bus_node_gc(slot->bus, slot->node_object_manager.node);
136 case BUS_NODE_VTABLE:
138 if (slot->node_vtable.node && slot->node_vtable.interface && slot->node_vtable.vtable) {
139 const sd_bus_vtable *v;
141 for (v = slot->node_vtable.vtable; v->type != _SD_BUS_VTABLE_END; v++) {
142 struct vtable_member *x = NULL;
146 case _SD_BUS_VTABLE_METHOD: {
147 struct vtable_member key;
149 key.path = slot->node_vtable.node->path;
150 key.interface = slot->node_vtable.interface;
151 key.member = v->x.method.member;
153 x = hashmap_remove(slot->bus->vtable_methods, &key);
157 case _SD_BUS_VTABLE_PROPERTY:
158 case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
159 struct vtable_member key;
161 key.path = slot->node_vtable.node->path;
162 key.interface = slot->node_vtable.interface;
163 key.member = v->x.method.member;
166 x = hashmap_remove(slot->bus->vtable_properties, &key);
174 free(slot->node_vtable.interface);
176 if (slot->node_vtable.node) {
177 LIST_REMOVE(vtables, slot->node_vtable.node->vtables, &slot->node_vtable);
178 slot->bus->nodes_modified = true;
180 bus_node_gc(slot->bus, slot->node_vtable.node);
187 slot->type = _BUS_SLOT_DISCONNECTED;
189 LIST_REMOVE(slots, bus->slots, slot);
195 _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
200 assert(slot->n_ref > 0);
202 if (slot->n_ref > 1) {
207 bus_slot_disconnect(slot);
213 _public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) {
214 assert_return(slot, NULL);
219 _public_ void *sd_bus_slot_get_userdata(sd_bus_slot *slot) {
220 assert_return(slot, NULL);
222 return slot->userdata;
225 _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
228 assert_return(slot, NULL);
230 ret = slot->userdata;
231 slot->userdata = userdata;
236 _public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
237 assert_return(slot, NULL);
238 assert_return(slot->type != _BUS_SLOT_DISCONNECTED, NULL);
240 if (slot->bus->current_slot != slot)
243 return slot->bus->current_message;