1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "alloc-util.h"
24 #include "bus-control.h"
25 #include "bus-objects.h"
27 #include "string-util.h"
29 sd_bus_slot
*bus_slot_allocate(
40 slot
= malloc0(offsetof(sd_bus_slot
, reply_callback
) + extra
);
47 slot
->floating
= floating
;
48 slot
->userdata
= userdata
;
53 LIST_PREPEND(slots
, bus
->slots
, slot
);
58 _public_ sd_bus_slot
* sd_bus_slot_ref(sd_bus_slot
*slot
) {
63 assert(slot
->n_ref
> 0);
69 void bus_slot_disconnect(sd_bus_slot
*slot
) {
79 case BUS_REPLY_CALLBACK
:
81 if (slot
->reply_callback
.cookie
!= 0)
82 ordered_hashmap_remove(slot
->bus
->reply_callbacks
, &slot
->reply_callback
.cookie
);
84 if (slot
->reply_callback
.timeout
!= 0)
85 prioq_remove(slot
->bus
->reply_callbacks_prioq
, &slot
->reply_callback
, &slot
->reply_callback
.prioq_idx
);
89 case BUS_FILTER_CALLBACK
:
90 slot
->bus
->filter_callbacks_modified
= true;
91 LIST_REMOVE(callbacks
, slot
->bus
->filter_callbacks
, &slot
->filter_callback
);
94 case BUS_MATCH_CALLBACK
:
96 if (slot
->match_added
)
97 bus_remove_match_internal(slot
->bus
, slot
->match_callback
.match_string
);
99 slot
->bus
->match_callbacks_modified
= true;
100 bus_match_remove(&slot
->bus
->match_callbacks
, &slot
->match_callback
);
102 free(slot
->match_callback
.match_string
);
106 case BUS_NODE_CALLBACK
:
108 if (slot
->node_callback
.node
) {
109 LIST_REMOVE(callbacks
, slot
->node_callback
.node
->callbacks
, &slot
->node_callback
);
110 slot
->bus
->nodes_modified
= true;
112 bus_node_gc(slot
->bus
, slot
->node_callback
.node
);
117 case BUS_NODE_ENUMERATOR
:
119 if (slot
->node_enumerator
.node
) {
120 LIST_REMOVE(enumerators
, slot
->node_enumerator
.node
->enumerators
, &slot
->node_enumerator
);
121 slot
->bus
->nodes_modified
= true;
123 bus_node_gc(slot
->bus
, slot
->node_enumerator
.node
);
128 case BUS_NODE_OBJECT_MANAGER
:
130 if (slot
->node_object_manager
.node
) {
131 LIST_REMOVE(object_managers
, slot
->node_object_manager
.node
->object_managers
, &slot
->node_object_manager
);
132 slot
->bus
->nodes_modified
= true;
134 bus_node_gc(slot
->bus
, slot
->node_object_manager
.node
);
139 case BUS_NODE_VTABLE
:
141 if (slot
->node_vtable
.node
&& slot
->node_vtable
.interface
&& slot
->node_vtable
.vtable
) {
142 const sd_bus_vtable
*v
;
144 for (v
= slot
->node_vtable
.vtable
; v
->type
!= _SD_BUS_VTABLE_END
; v
++) {
145 struct vtable_member
*x
= NULL
;
149 case _SD_BUS_VTABLE_METHOD
: {
150 struct vtable_member key
;
152 key
.path
= slot
->node_vtable
.node
->path
;
153 key
.interface
= slot
->node_vtable
.interface
;
154 key
.member
= v
->x
.method
.member
;
156 x
= hashmap_remove(slot
->bus
->vtable_methods
, &key
);
160 case _SD_BUS_VTABLE_PROPERTY
:
161 case _SD_BUS_VTABLE_WRITABLE_PROPERTY
: {
162 struct vtable_member key
;
164 key
.path
= slot
->node_vtable
.node
->path
;
165 key
.interface
= slot
->node_vtable
.interface
;
166 key
.member
= v
->x
.method
.member
;
169 x
= hashmap_remove(slot
->bus
->vtable_properties
, &key
);
177 free(slot
->node_vtable
.interface
);
179 if (slot
->node_vtable
.node
) {
180 LIST_REMOVE(vtables
, slot
->node_vtable
.node
->vtables
, &slot
->node_vtable
);
181 slot
->bus
->nodes_modified
= true;
183 bus_node_gc(slot
->bus
, slot
->node_vtable
.node
);
189 assert_not_reached("Wut? Unknown slot type?");
194 slot
->type
= _BUS_SLOT_INVALID
;
196 LIST_REMOVE(slots
, bus
->slots
, slot
);
202 _public_ sd_bus_slot
* sd_bus_slot_unref(sd_bus_slot
*slot
) {
207 assert(slot
->n_ref
> 0);
209 if (slot
->n_ref
> 1) {
214 bus_slot_disconnect(slot
);
215 free(slot
->description
);
219 _public_ sd_bus
* sd_bus_slot_get_bus(sd_bus_slot
*slot
) {
220 assert_return(slot
, NULL
);
225 _public_
void *sd_bus_slot_get_userdata(sd_bus_slot
*slot
) {
226 assert_return(slot
, NULL
);
228 return slot
->userdata
;
231 _public_
void *sd_bus_slot_set_userdata(sd_bus_slot
*slot
, void *userdata
) {
234 assert_return(slot
, NULL
);
236 ret
= slot
->userdata
;
237 slot
->userdata
= userdata
;
242 _public_ sd_bus_message
*sd_bus_slot_get_current_message(sd_bus_slot
*slot
) {
243 assert_return(slot
, NULL
);
244 assert_return(slot
->type
>= 0, NULL
);
246 if (slot
->bus
->current_slot
!= slot
)
249 return slot
->bus
->current_message
;
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
);
256 if (slot
->bus
->current_slot
!= slot
)
259 return slot
->bus
->current_handler
;
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
);
266 if (slot
->bus
->current_slot
!= slot
)
269 return slot
->bus
->current_userdata
;
272 _public_
int sd_bus_slot_set_description(sd_bus_slot
*slot
, const char *description
) {
273 assert_return(slot
, -EINVAL
);
275 return free_and_strdup(&slot
->description
, description
);
278 _public_
int sd_bus_slot_get_description(sd_bus_slot
*slot
, const char **description
) {
279 assert_return(slot
, -EINVAL
);
280 assert_return(description
, -EINVAL
);
281 assert_return(slot
->description
, -ENXIO
);
283 *description
= slot
->description
;