bus: optionally call a callbacks for cleanup
This adds a function sd_bus_slot_set_destroy_callback() to set a function which can free userdata or perform other cleanups. sd_bus_slot_get_destory_callback() queries the callback, and is included for completeness. Without something like this, for floating asynchronous callbacks, which might be called or not, depending on the sequence of events, it's hard to perform resource cleanup. The alternative would be to always perform the cleanup from the caller too, but that requires more coordination and keeping of some shared state. It's nicer to keep the cleanup contained between the callback and the function that requests the callback.
This commit is contained in:
@@ -563,6 +563,8 @@ global:
|
||||
sd_bus_open_system_with_description;
|
||||
sd_bus_slot_get_floating;
|
||||
sd_bus_slot_set_floating;
|
||||
sd_bus_slot_get_destroy_callback;
|
||||
sd_bus_slot_set_destroy_callback;
|
||||
sd_event_add_inotify;
|
||||
sd_event_source_get_inotify_mask;
|
||||
} LIBSYSTEMD_238;
|
||||
|
||||
@@ -127,6 +127,7 @@ struct sd_bus_slot {
|
||||
unsigned n_ref;
|
||||
sd_bus *bus;
|
||||
void *userdata;
|
||||
sd_bus_destroy_t destroy_callback;
|
||||
BusSlotType type:5;
|
||||
|
||||
/* Slots can be "floating" or not. If they are not floating (the usual case) then they reference the bus object
|
||||
|
||||
@@ -203,6 +203,10 @@ _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
|
||||
}
|
||||
|
||||
bus_slot_disconnect(slot);
|
||||
|
||||
if (slot->destroy_callback)
|
||||
slot->destroy_callback(slot->userdata);
|
||||
|
||||
free(slot->description);
|
||||
return mfree(slot);
|
||||
}
|
||||
@@ -230,6 +234,22 @@ _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_slot_set_destroy_callback(sd_bus_slot *slot, sd_bus_destroy_t callback) {
|
||||
assert_return(slot, -EINVAL);
|
||||
|
||||
slot->destroy_callback = callback;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_slot_get_destroy_callback(sd_bus_slot *slot, sd_bus_destroy_t *callback) {
|
||||
assert_return(slot, -EINVAL);
|
||||
|
||||
if (callback)
|
||||
*callback = slot->destroy_callback;
|
||||
|
||||
return !!slot->destroy_callback;
|
||||
}
|
||||
|
||||
_public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
|
||||
assert_return(slot, NULL);
|
||||
assert_return(slot->type >= 0, NULL);
|
||||
|
||||
Reference in New Issue
Block a user