1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
24 #include "alloc-util.h"
25 #include "bus-control.h"
26 #include "bus-objects.h"
28 #include "string-util.h"
30 sd_bus_slot
*bus_slot_allocate(
41 slot
= malloc0(offsetof(sd_bus_slot
, reply_callback
) + extra
);
48 slot
->floating
= floating
;
49 slot
->userdata
= userdata
;
54 LIST_PREPEND(slots
, bus
->slots
, slot
);
59 _public_ sd_bus_slot
* sd_bus_slot_ref(sd_bus_slot
*slot
) {
60 assert_return(slot
, NULL
);
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
;