2 This file is part of systemd.
4 Copyright 2013 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "alloc-util.h"
23 #include "bus-control.h"
24 #include "bus-objects.h"
26 #include "string-util.h"
28 sd_bus_slot
*bus_slot_allocate(
39 slot
= malloc0(offsetof(sd_bus_slot
, reply_callback
) + extra
);
46 slot
->floating
= floating
;
47 slot
->userdata
= userdata
;
52 LIST_PREPEND(slots
, bus
->slots
, slot
);
57 _public_ sd_bus_slot
* sd_bus_slot_ref(sd_bus_slot
*slot
) {
62 assert(slot
->n_ref
> 0);
68 void bus_slot_disconnect(sd_bus_slot
*slot
) {
78 case BUS_REPLY_CALLBACK
:
80 if (slot
->reply_callback
.cookie
!= 0)
81 ordered_hashmap_remove(slot
->bus
->reply_callbacks
, &slot
->reply_callback
.cookie
);
83 if (slot
->reply_callback
.timeout
!= 0)
84 prioq_remove(slot
->bus
->reply_callbacks_prioq
, &slot
->reply_callback
, &slot
->reply_callback
.prioq_idx
);
88 case BUS_FILTER_CALLBACK
:
89 slot
->bus
->filter_callbacks_modified
= true;
90 LIST_REMOVE(callbacks
, slot
->bus
->filter_callbacks
, &slot
->filter_callback
);
93 case BUS_MATCH_CALLBACK
:
95 if (slot
->match_added
)
96 bus_remove_match_internal(slot
->bus
, slot
->match_callback
.match_string
, slot
->match_callback
.cookie
);
98 slot
->bus
->match_callbacks_modified
= true;
99 bus_match_remove(&slot
->bus
->match_callbacks
, &slot
->match_callback
);
101 free(slot
->match_callback
.match_string
);
105 case BUS_NODE_CALLBACK
:
107 if (slot
->node_callback
.node
) {
108 LIST_REMOVE(callbacks
, slot
->node_callback
.node
->callbacks
, &slot
->node_callback
);
109 slot
->bus
->nodes_modified
= true;
111 bus_node_gc(slot
->bus
, slot
->node_callback
.node
);
116 case BUS_NODE_ENUMERATOR
:
118 if (slot
->node_enumerator
.node
) {
119 LIST_REMOVE(enumerators
, slot
->node_enumerator
.node
->enumerators
, &slot
->node_enumerator
);
120 slot
->bus
->nodes_modified
= true;
122 bus_node_gc(slot
->bus
, slot
->node_enumerator
.node
);
127 case BUS_NODE_OBJECT_MANAGER
:
129 if (slot
->node_object_manager
.node
) {
130 LIST_REMOVE(object_managers
, slot
->node_object_manager
.node
->object_managers
, &slot
->node_object_manager
);
131 slot
->bus
->nodes_modified
= true;
133 bus_node_gc(slot
->bus
, slot
->node_object_manager
.node
);
138 case BUS_NODE_VTABLE
:
140 if (slot
->node_vtable
.node
&& slot
->node_vtable
.interface
&& slot
->node_vtable
.vtable
) {
141 const sd_bus_vtable
*v
;
143 for (v
= slot
->node_vtable
.vtable
; v
->type
!= _SD_BUS_VTABLE_END
; v
++) {
144 struct vtable_member
*x
= NULL
;
148 case _SD_BUS_VTABLE_METHOD
: {
149 struct vtable_member key
;
151 key
.path
= slot
->node_vtable
.node
->path
;
152 key
.interface
= slot
->node_vtable
.interface
;
153 key
.member
= v
->x
.method
.member
;
155 x
= hashmap_remove(slot
->bus
->vtable_methods
, &key
);
159 case _SD_BUS_VTABLE_PROPERTY
:
160 case _SD_BUS_VTABLE_WRITABLE_PROPERTY
: {
161 struct vtable_member key
;
163 key
.path
= slot
->node_vtable
.node
->path
;
164 key
.interface
= slot
->node_vtable
.interface
;
165 key
.member
= v
->x
.method
.member
;
168 x
= hashmap_remove(slot
->bus
->vtable_properties
, &key
);
176 free(slot
->node_vtable
.interface
);
178 if (slot
->node_vtable
.node
) {
179 LIST_REMOVE(vtables
, slot
->node_vtable
.node
->vtables
, &slot
->node_vtable
);
180 slot
->bus
->nodes_modified
= true;
182 bus_node_gc(slot
->bus
, slot
->node_vtable
.node
);
188 assert_not_reached("Wut? Unknown slot type?");
193 slot
->type
= _BUS_SLOT_INVALID
;
195 LIST_REMOVE(slots
, bus
->slots
, slot
);
201 _public_ sd_bus_slot
* sd_bus_slot_unref(sd_bus_slot
*slot
) {
206 assert(slot
->n_ref
> 0);
208 if (slot
->n_ref
> 1) {
213 bus_slot_disconnect(slot
);
214 free(slot
->description
);
220 _public_ sd_bus
* sd_bus_slot_get_bus(sd_bus_slot
*slot
) {
221 assert_return(slot
, NULL
);
226 _public_
void *sd_bus_slot_get_userdata(sd_bus_slot
*slot
) {
227 assert_return(slot
, NULL
);
229 return slot
->userdata
;
232 _public_
void *sd_bus_slot_set_userdata(sd_bus_slot
*slot
, void *userdata
) {
235 assert_return(slot
, NULL
);
237 ret
= slot
->userdata
;
238 slot
->userdata
= userdata
;
243 _public_ sd_bus_message
*sd_bus_slot_get_current_message(sd_bus_slot
*slot
) {
244 assert_return(slot
, NULL
);
245 assert_return(slot
->type
>= 0, NULL
);
247 if (slot
->bus
->current_slot
!= slot
)
250 return slot
->bus
->current_message
;
253 _public_ sd_bus_message_handler_t
sd_bus_slot_get_current_handler(sd_bus_slot
*slot
) {
254 assert_return(slot
, NULL
);
255 assert_return(slot
->type
>= 0, NULL
);
257 if (slot
->bus
->current_slot
!= slot
)
260 return slot
->bus
->current_handler
;
263 _public_
void* sd_bus_slot_get_current_userdata(sd_bus_slot
*slot
) {
264 assert_return(slot
, NULL
);
265 assert_return(slot
->type
>= 0, NULL
);
267 if (slot
->bus
->current_slot
!= slot
)
270 return slot
->bus
->current_userdata
;
273 _public_
int sd_bus_slot_set_description(sd_bus_slot
*slot
, const char *description
) {
274 assert_return(slot
, -EINVAL
);
276 return free_and_strdup(&slot
->description
, description
);
279 _public_
int sd_bus_slot_get_description(sd_bus_slot
*slot
, const char **description
) {
280 assert_return(slot
, -EINVAL
);
281 assert_return(description
, -EINVAL
);
282 assert_return(slot
->description
, -ENXIO
);
284 *description
= slot
->description
;