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 "bus-control.h"
25 #include "bus-objects.h"
26 #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
) {
59 assert_return(slot
, NULL
);
61 assert(slot
->n_ref
> 0);
67 void bus_slot_disconnect(sd_bus_slot
*slot
) {
77 case BUS_REPLY_CALLBACK
:
79 if (slot
->reply_callback
.cookie
!= 0)
80 ordered_hashmap_remove(slot
->bus
->reply_callbacks
, &slot
->reply_callback
.cookie
);
82 if (slot
->reply_callback
.timeout
!= 0)
83 prioq_remove(slot
->bus
->reply_callbacks_prioq
, &slot
->reply_callback
, &slot
->reply_callback
.prioq_idx
);
87 case BUS_FILTER_CALLBACK
:
88 slot
->bus
->filter_callbacks_modified
= true;
89 LIST_REMOVE(callbacks
, slot
->bus
->filter_callbacks
, &slot
->filter_callback
);
92 case BUS_MATCH_CALLBACK
:
94 if (slot
->match_added
)
95 bus_remove_match_internal(slot
->bus
, slot
->match_callback
.match_string
, slot
->match_callback
.cookie
);
97 slot
->bus
->match_callbacks_modified
= true;
98 bus_match_remove(&slot
->bus
->match_callbacks
, &slot
->match_callback
);
100 free(slot
->match_callback
.match_string
);
104 case BUS_NODE_CALLBACK
:
106 if (slot
->node_callback
.node
) {
107 LIST_REMOVE(callbacks
, slot
->node_callback
.node
->callbacks
, &slot
->node_callback
);
108 slot
->bus
->nodes_modified
= true;
110 bus_node_gc(slot
->bus
, slot
->node_callback
.node
);
115 case BUS_NODE_ENUMERATOR
:
117 if (slot
->node_enumerator
.node
) {
118 LIST_REMOVE(enumerators
, slot
->node_enumerator
.node
->enumerators
, &slot
->node_enumerator
);
119 slot
->bus
->nodes_modified
= true;
121 bus_node_gc(slot
->bus
, slot
->node_enumerator
.node
);
126 case BUS_NODE_OBJECT_MANAGER
:
128 if (slot
->node_object_manager
.node
) {
129 LIST_REMOVE(object_managers
, slot
->node_object_manager
.node
->object_managers
, &slot
->node_object_manager
);
130 slot
->bus
->nodes_modified
= true;
132 bus_node_gc(slot
->bus
, slot
->node_object_manager
.node
);
137 case BUS_NODE_VTABLE
:
139 if (slot
->node_vtable
.node
&& slot
->node_vtable
.interface
&& slot
->node_vtable
.vtable
) {
140 const sd_bus_vtable
*v
;
142 for (v
= slot
->node_vtable
.vtable
; v
->type
!= _SD_BUS_VTABLE_END
; v
++) {
143 struct vtable_member
*x
= NULL
;
147 case _SD_BUS_VTABLE_METHOD
: {
148 struct vtable_member key
;
150 key
.path
= slot
->node_vtable
.node
->path
;
151 key
.interface
= slot
->node_vtable
.interface
;
152 key
.member
= v
->x
.method
.member
;
154 x
= hashmap_remove(slot
->bus
->vtable_methods
, &key
);
158 case _SD_BUS_VTABLE_PROPERTY
:
159 case _SD_BUS_VTABLE_WRITABLE_PROPERTY
: {
160 struct vtable_member key
;
162 key
.path
= slot
->node_vtable
.node
->path
;
163 key
.interface
= slot
->node_vtable
.interface
;
164 key
.member
= v
->x
.method
.member
;
167 x
= hashmap_remove(slot
->bus
->vtable_properties
, &key
);
175 free(slot
->node_vtable
.interface
);
177 if (slot
->node_vtable
.node
) {
178 LIST_REMOVE(vtables
, slot
->node_vtable
.node
->vtables
, &slot
->node_vtable
);
179 slot
->bus
->nodes_modified
= true;
181 bus_node_gc(slot
->bus
, slot
->node_vtable
.node
);
187 assert_not_reached("Wut? Unknown slot type?");
192 slot
->type
= _BUS_SLOT_INVALID
;
194 LIST_REMOVE(slots
, bus
->slots
, slot
);
200 _public_ sd_bus_slot
* sd_bus_slot_unref(sd_bus_slot
*slot
) {
205 assert(slot
->n_ref
> 0);
207 if (slot
->n_ref
> 1) {
212 bus_slot_disconnect(slot
);
213 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
;