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