]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-slot.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-slot.c
CommitLineData
19befb2d
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
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.
12
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.
17
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/>.
20***/
21
22#include "sd-bus.h"
07630cea 23
19befb2d
LP
24#include "bus-control.h"
25#include "bus-objects.h"
07630cea 26#include "string-util.h"
19befb2d
LP
27#include "bus-slot.h"
28
29sd_bus_slot *bus_slot_allocate(
30 sd_bus *bus,
31 bool floating,
32 BusSlotType type,
33 size_t extra,
34 void *userdata) {
35
36 sd_bus_slot *slot;
37
38 assert(bus);
39
40 slot = malloc0(offsetof(sd_bus_slot, reply_callback) + extra);
41 if (!slot)
42 return NULL;
43
44 slot->n_ref = 1;
45 slot->type = type;
46 slot->bus = bus;
47 slot->floating = floating;
48 slot->userdata = userdata;
49
50 if (!floating)
51 sd_bus_ref(bus);
52
53 LIST_PREPEND(slots, bus->slots, slot);
54
55 return slot;
56}
57
58_public_ sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot) {
59 assert_return(slot, NULL);
60
61 assert(slot->n_ref > 0);
62
63 slot->n_ref++;
64 return slot;
65}
66
67void bus_slot_disconnect(sd_bus_slot *slot) {
68 sd_bus *bus;
69
70 assert(slot);
71
a71fe8b8 72 if (!slot->bus)
19befb2d
LP
73 return;
74
a71fe8b8
LP
75 switch (slot->type) {
76
19befb2d
LP
77 case BUS_REPLY_CALLBACK:
78
79 if (slot->reply_callback.cookie != 0)
c9fe4af7 80 ordered_hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
19befb2d
LP
81
82 if (slot->reply_callback.timeout != 0)
83 prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
84
85 break;
86
87 case BUS_FILTER_CALLBACK:
88 slot->bus->filter_callbacks_modified = true;
89 LIST_REMOVE(callbacks, slot->bus->filter_callbacks, &slot->filter_callback);
90 break;
91
92 case BUS_MATCH_CALLBACK:
93
cc65fe5e 94 if (slot->match_added)
19befb2d
LP
95 bus_remove_match_internal(slot->bus, slot->match_callback.match_string, slot->match_callback.cookie);
96
97 slot->bus->match_callbacks_modified = true;
98 bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback);
99
100 free(slot->match_callback.match_string);
101
102 break;
103
104 case BUS_NODE_CALLBACK:
105
106 if (slot->node_callback.node) {
107 LIST_REMOVE(callbacks, slot->node_callback.node->callbacks, &slot->node_callback);
108 slot->bus->nodes_modified = true;
109
110 bus_node_gc(slot->bus, slot->node_callback.node);
111 }
112
113 break;
114
115 case BUS_NODE_ENUMERATOR:
116
117 if (slot->node_enumerator.node) {
118 LIST_REMOVE(enumerators, slot->node_enumerator.node->enumerators, &slot->node_enumerator);
119 slot->bus->nodes_modified = true;
120
121 bus_node_gc(slot->bus, slot->node_enumerator.node);
122 }
123
124 break;
125
126 case BUS_NODE_OBJECT_MANAGER:
127
128 if (slot->node_object_manager.node) {
129 LIST_REMOVE(object_managers, slot->node_object_manager.node->object_managers, &slot->node_object_manager);
130 slot->bus->nodes_modified = true;
131
132 bus_node_gc(slot->bus, slot->node_object_manager.node);
133 }
134
135 break;
136
137 case BUS_NODE_VTABLE:
138
139 if (slot->node_vtable.node && slot->node_vtable.interface && slot->node_vtable.vtable) {
140 const sd_bus_vtable *v;
141
142 for (v = slot->node_vtable.vtable; v->type != _SD_BUS_VTABLE_END; v++) {
143 struct vtable_member *x = NULL;
144
145 switch (v->type) {
146
147 case _SD_BUS_VTABLE_METHOD: {
148 struct vtable_member key;
149
150 key.path = slot->node_vtable.node->path;
151 key.interface = slot->node_vtable.interface;
152 key.member = v->x.method.member;
153
154 x = hashmap_remove(slot->bus->vtable_methods, &key);
155 break;
156 }
157
158 case _SD_BUS_VTABLE_PROPERTY:
159 case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
160 struct vtable_member key;
161
162 key.path = slot->node_vtable.node->path;
163 key.interface = slot->node_vtable.interface;
164 key.member = v->x.method.member;
165
166
167 x = hashmap_remove(slot->bus->vtable_properties, &key);
168 break;
169 }}
170
171 free(x);
172 }
173 }
174
175 free(slot->node_vtable.interface);
176
177 if (slot->node_vtable.node) {
178 LIST_REMOVE(vtables, slot->node_vtable.node->vtables, &slot->node_vtable);
179 slot->bus->nodes_modified = true;
180
181 bus_node_gc(slot->bus, slot->node_vtable.node);
182 }
183
184 break;
a71fe8b8
LP
185
186 default:
187 assert_not_reached("Wut? Unknown slot type?");
19befb2d 188 }
a71fe8b8 189
19befb2d
LP
190 bus = slot->bus;
191
a71fe8b8 192 slot->type = _BUS_SLOT_INVALID;
19befb2d
LP
193 slot->bus = NULL;
194 LIST_REMOVE(slots, bus->slots, slot);
195
196 if (!slot->floating)
197 sd_bus_unref(bus);
198}
199
200_public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
201
202 if (!slot)
203 return NULL;
204
205 assert(slot->n_ref > 0);
206
207 if (slot->n_ref > 1) {
208 slot->n_ref --;
209 return NULL;
210 }
211
212 bus_slot_disconnect(slot);
9cbfc66c 213 free(slot->description);
19befb2d
LP
214 free(slot);
215
216 return NULL;
217}
218
219_public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) {
220 assert_return(slot, NULL);
221
222 return slot->bus;
223}
224
225_public_ void *sd_bus_slot_get_userdata(sd_bus_slot *slot) {
226 assert_return(slot, NULL);
227
228 return slot->userdata;
229}
230
231_public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
232 void *ret;
233
234 assert_return(slot, NULL);
235
236 ret = slot->userdata;
237 slot->userdata = userdata;
238
239 return ret;
240}
241
242_public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
243 assert_return(slot, NULL);
a71fe8b8 244 assert_return(slot->type >= 0, NULL);
19befb2d
LP
245
246 if (slot->bus->current_slot != slot)
247 return NULL;
248
249 return slot->bus->current_message;
250}
caa82984
LP
251
252_public_ sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot) {
253 assert_return(slot, NULL);
254 assert_return(slot->type >= 0, NULL);
255
256 if (slot->bus->current_slot != slot)
257 return NULL;
258
259 return slot->bus->current_handler;
260}
261
262_public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) {
263 assert_return(slot, NULL);
264 assert_return(slot->type >= 0, NULL);
265
266 if (slot->bus->current_slot != slot)
267 return NULL;
268
269 return slot->bus->current_userdata;
270}
9cbfc66c
LP
271
272_public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description) {
273 assert_return(slot, -EINVAL);
274
275 return free_and_strdup(&slot->description, description);
276}
277
839b6dbb 278_public_ int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description) {
9cbfc66c
LP
279 assert_return(slot, -EINVAL);
280 assert_return(description, -EINVAL);
281 assert_return(slot->description, -ENXIO);
282
283 *description = slot->description;
284 return 0;
285}