1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Lennart Poettering
10 #include "alloc-util.h"
11 #include "bus-control.h"
12 #include "bus-objects.h"
14 #include "string-util.h"
16 sd_bus_slot
*bus_slot_allocate(
27 slot
= malloc0(offsetof(sd_bus_slot
, reply_callback
) + extra
);
34 slot
->floating
= floating
;
35 slot
->userdata
= userdata
;
40 LIST_PREPEND(slots
, bus
->slots
, slot
);
45 _public_ sd_bus_slot
* sd_bus_slot_ref(sd_bus_slot
*slot
) {
50 assert(slot
->n_ref
> 0);
56 void bus_slot_disconnect(sd_bus_slot
*slot
) {
66 case BUS_REPLY_CALLBACK
:
68 if (slot
->reply_callback
.cookie
!= 0)
69 ordered_hashmap_remove(slot
->bus
->reply_callbacks
, &slot
->reply_callback
.cookie
);
71 if (slot
->reply_callback
.timeout_usec
!= 0)
72 prioq_remove(slot
->bus
->reply_callbacks_prioq
, &slot
->reply_callback
, &slot
->reply_callback
.prioq_idx
);
76 case BUS_FILTER_CALLBACK
:
77 slot
->bus
->filter_callbacks_modified
= true;
78 LIST_REMOVE(callbacks
, slot
->bus
->filter_callbacks
, &slot
->filter_callback
);
81 case BUS_MATCH_CALLBACK
:
83 if (slot
->match_added
)
84 (void) bus_remove_match_internal(slot
->bus
, slot
->match_callback
.match_string
);
86 if (slot
->match_callback
.install_slot
) {
87 bus_slot_disconnect(slot
->match_callback
.install_slot
);
88 slot
->match_callback
.install_slot
= sd_bus_slot_unref(slot
->match_callback
.install_slot
);
91 slot
->bus
->match_callbacks_modified
= true;
92 bus_match_remove(&slot
->bus
->match_callbacks
, &slot
->match_callback
);
94 slot
->match_callback
.match_string
= mfree(slot
->match_callback
.match_string
);
98 case BUS_NODE_CALLBACK
:
100 if (slot
->node_callback
.node
) {
101 LIST_REMOVE(callbacks
, slot
->node_callback
.node
->callbacks
, &slot
->node_callback
);
102 slot
->bus
->nodes_modified
= true;
104 bus_node_gc(slot
->bus
, slot
->node_callback
.node
);
109 case BUS_NODE_ENUMERATOR
:
111 if (slot
->node_enumerator
.node
) {
112 LIST_REMOVE(enumerators
, slot
->node_enumerator
.node
->enumerators
, &slot
->node_enumerator
);
113 slot
->bus
->nodes_modified
= true;
115 bus_node_gc(slot
->bus
, slot
->node_enumerator
.node
);
120 case BUS_NODE_OBJECT_MANAGER
:
122 if (slot
->node_object_manager
.node
) {
123 LIST_REMOVE(object_managers
, slot
->node_object_manager
.node
->object_managers
, &slot
->node_object_manager
);
124 slot
->bus
->nodes_modified
= true;
126 bus_node_gc(slot
->bus
, slot
->node_object_manager
.node
);
131 case BUS_NODE_VTABLE
:
133 if (slot
->node_vtable
.node
&& slot
->node_vtable
.interface
&& slot
->node_vtable
.vtable
) {
134 const sd_bus_vtable
*v
;
136 for (v
= slot
->node_vtable
.vtable
; v
->type
!= _SD_BUS_VTABLE_END
; v
++) {
137 struct vtable_member
*x
= NULL
;
141 case _SD_BUS_VTABLE_METHOD
: {
142 struct vtable_member key
;
144 key
.path
= slot
->node_vtable
.node
->path
;
145 key
.interface
= slot
->node_vtable
.interface
;
146 key
.member
= v
->x
.method
.member
;
148 x
= hashmap_remove(slot
->bus
->vtable_methods
, &key
);
152 case _SD_BUS_VTABLE_PROPERTY
:
153 case _SD_BUS_VTABLE_WRITABLE_PROPERTY
: {
154 struct vtable_member key
;
156 key
.path
= slot
->node_vtable
.node
->path
;
157 key
.interface
= slot
->node_vtable
.interface
;
158 key
.member
= v
->x
.method
.member
;
160 x
= hashmap_remove(slot
->bus
->vtable_properties
, &key
);
168 slot
->node_vtable
.interface
= mfree(slot
->node_vtable
.interface
);
170 if (slot
->node_vtable
.node
) {
171 LIST_REMOVE(vtables
, slot
->node_vtable
.node
->vtables
, &slot
->node_vtable
);
172 slot
->bus
->nodes_modified
= true;
174 bus_node_gc(slot
->bus
, slot
->node_vtable
.node
);
180 assert_not_reached("Wut? Unknown slot type?");
185 slot
->type
= _BUS_SLOT_INVALID
;
187 LIST_REMOVE(slots
, bus
->slots
, slot
);
193 _public_ sd_bus_slot
* sd_bus_slot_unref(sd_bus_slot
*slot
) {
198 assert(slot
->n_ref
> 0);
200 if (slot
->n_ref
> 1) {
205 bus_slot_disconnect(slot
);
206 free(slot
->description
);
210 _public_ sd_bus
* sd_bus_slot_get_bus(sd_bus_slot
*slot
) {
211 assert_return(slot
, NULL
);
216 _public_
void *sd_bus_slot_get_userdata(sd_bus_slot
*slot
) {
217 assert_return(slot
, NULL
);
219 return slot
->userdata
;
222 _public_
void *sd_bus_slot_set_userdata(sd_bus_slot
*slot
, void *userdata
) {
225 assert_return(slot
, NULL
);
227 ret
= slot
->userdata
;
228 slot
->userdata
= userdata
;
233 _public_ sd_bus_message
*sd_bus_slot_get_current_message(sd_bus_slot
*slot
) {
234 assert_return(slot
, NULL
);
235 assert_return(slot
->type
>= 0, NULL
);
237 if (slot
->bus
->current_slot
!= slot
)
240 return slot
->bus
->current_message
;
243 _public_ sd_bus_message_handler_t
sd_bus_slot_get_current_handler(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_handler
;
253 _public_
void* sd_bus_slot_get_current_userdata(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_userdata
;
263 _public_
int sd_bus_slot_set_description(sd_bus_slot
*slot
, const char *description
) {
264 assert_return(slot
, -EINVAL
);
266 return free_and_strdup(&slot
->description
, description
);
269 _public_
int sd_bus_slot_get_description(sd_bus_slot
*slot
, const char **description
) {
270 assert_return(slot
, -EINVAL
);
271 assert_return(description
, -EINVAL
);
272 assert_return(slot
->description
, -ENXIO
);
274 *description
= slot
->description
;