From: Lennart Poettering Date: Thu, 7 Jun 2018 10:40:35 +0000 (+0200) Subject: sd-event: add destroy callback logic to sd-event too X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=097513b6bea999cbb3a6dfee15010239d2b85a6c;p=elogind.git sd-event: add destroy callback logic to sd-event too This adds what has been added to sd_bus_slot and sd_bus_track to sd_event too. --- diff --git a/man/rules/meson.build b/man/rules/meson.build index 88c832815..13295da9d 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -317,6 +317,10 @@ manpages = [ '3', ['sd_event_source_get_description'], ''], + ['sd_event_source_set_destroy_callback', + '3', + ['sd_event_destroy_t', 'sd_event_source_get_destroy_callback'], + ''], ['sd_event_source_set_enabled', '3', ['SD_EVENT_OFF', diff --git a/man/sd_event_source_set_destroy_callback.xml b/man/sd_event_source_set_destroy_callback.xml new file mode 100644 index 000000000..aa6d0e1b3 --- /dev/null +++ b/man/sd_event_source_set_destroy_callback.xml @@ -0,0 +1,112 @@ + + + + + + + + + sd_event_source_set_destroy_callback + elogind + + + + sd_event_source_set_destroy_callback + 3 + + + + sd_event_source_set_destroy_callback + sd_event_source_get_destroy_callback + sd_event_destroy_t + + Define the callback function for resource cleanup. + + + + + #include <elogind/sd-event.h> + + + typedef int (*sd_event_destroy_t) + void *userdata + + + + int sd_event_source_set_destroy_callback + sd_event_source *source + sd_event_destroy_t callback + + + + int sd_event_source_get_destroy_callback + sd_event_source *source + sd_event_destroy_t *callback + + + + + + + Description + + sd_event_source_set_destroy_callback() sets callback as the + callback function to be called right before the event source object source is + deallocated. The userdata pointer from the event source object will be passed as the + userdata parameter. This pointer can be set by an argument to the constructor functions, see + sd_event_add_io3, or directly, + see + sd_event_source_set_userdata3. + This callback function is called even if userdata is NULL. Note that + this callback is invoked at a time where the event source object itself is already invalidated, and executing + operations or taking new references to the event source object is not permissible. + + sd_event_source_get_destroy_callback() returns the current callback + for source in the callback parameter. + + + + Return Value + + On success, sd_event_source_set_destroy_callback() returns 0 or a positive integer. On + failure, it returns a negative errno-style error code. + + sd_event_source_get_destroy_callback() returns positive if the destroy callback function + is set, 0 if not. On failure, returns a negative errno-style error code. + + + + Errors + + Returned errors may indicate the following problems: + + + + -EINVAL + + The source parameter is NULL. + + + + + + + + See Also + + + elogind1, + sd-event3, + sd_event_add_io3, + sd_event_add_time3, + sd_event_add_signal3, + sd_event_add_child3, + sd_event_add_inotify3, + sd_event_add_defer3, + sd_event_source_set_userdata3 + + + + diff --git a/src/libelogind/libelogind.sym b/src/libelogind/libelogind.sym index e65c0d1b8..e63668b2a 100644 --- a/src/libelogind/libelogind.sym +++ b/src/libelogind/libelogind.sym @@ -575,4 +575,6 @@ global: sd_bus_track_set_destroy_callback; sd_event_add_inotify; sd_event_source_get_inotify_mask; + sd_event_source_set_destroy_callback; + sd_event_source_get_destroy_callback; } LIBSYSTEMD_238; diff --git a/src/libelogind/sd-event/sd-event.c b/src/libelogind/sd-event/sd-event.c index 3f9691227..ca104281e 100644 --- a/src/libelogind/sd-event/sd-event.c +++ b/src/libelogind/sd-event/sd-event.c @@ -106,6 +106,8 @@ struct sd_event_source { uint64_t pending_iteration; uint64_t prepare_iteration; + sd_event_destroy_t destroy_callback; + LIST_FIELDS(sd_event_source, sources); union { @@ -1016,7 +1018,10 @@ static void source_free(sd_event_source *s) { source_disconnect(s); if (s->type == SOURCE_IO && s->io.owned) - safe_close(s->io.fd); + s->io.fd = safe_close(s->io.fd); + + if (s->destroy_callback) + s->destroy_callback(s->userdata); free(s->description); free(s); @@ -3775,3 +3780,19 @@ _public_ int sd_event_get_iteration(sd_event *e, uint64_t *ret) { *ret = e->iteration; return 0; } + +_public_ int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback) { + assert_return(s, -EINVAL); + + s->destroy_callback = callback; + return 0; +} + +_public_ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret) { + assert_return(s, -EINVAL); + + if (ret) + *ret = s->destroy_callback; + + return !!s->destroy_callback; +} diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h index 422393888..e6bea9d40 100644 --- a/src/systemd/sd-event.h +++ b/src/systemd/sd-event.h @@ -80,6 +80,7 @@ typedef int (*sd_event_child_handler_t)(sd_event_source *s, const siginfo_t *si, typedef void* sd_event_child_handler_t; #endif typedef int (*sd_event_inotify_handler_t)(sd_event_source *s, const struct inotify_event *event, void *userdata); +typedef void (*sd_event_destroy_t)(void *userdata); int sd_event_default(sd_event **e); @@ -143,6 +144,8 @@ int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock); int sd_event_source_get_signal(sd_event_source *s); int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid); int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret); +int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback); +int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret); /* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */ _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref);