chiark / gitweb /
Add fd close support to sd_event_source
authorNathaniel McCallum <npmccallum@redhat.com>
Wed, 24 Jan 2018 14:45:48 +0000 (09:45 -0500)
committerSven Eden <yamakuzure@gmx.net>
Wed, 30 May 2018 05:50:15 +0000 (07:50 +0200)
It is often the case that a file descriptor and its corresponding IO
sd_event_source share a life span. When this is the case, developers will
have to unref the event source and close the file descriptor. Instead, we
can just have the event source take ownership of the file descriptor and
close it when the event source is freed. This is especially useful when
combined with cleanup attributes and sd_event_source_unrefp().

This patch adds two new public functions:

    sd_event_source_get_io_fd_own()
    sd_event_source_set_io_fd_own()

src/libelogind/libelogind.sym
src/libelogind/sd-event/sd-event.c
src/systemd/sd-event.h

index 2dc592dd0ef1c7a94f0a1e24b02afdb6e81e9681..107f5d14b3089d2ba6be1d8393130372b280c021 100644 (file)
@@ -552,4 +552,6 @@ global:
         sd_bus_set_sender;
         sd_bus_get_sender;
         sd_bus_message_set_sender;
+        sd_event_source_get_io_fd_own;
+        sd_event_source_set_io_fd_own;
 } LIBSYSTEMD_236;
index be78a367193722c2b65224fd65acbc467d3fd0eb..cb9b3a4545c10e8e236f2128e415de3fbe1b064f 100644 (file)
@@ -122,6 +122,7 @@ struct sd_event_source {
                         uint32_t events;
                         uint32_t revents;
                         bool registered:1;
+                        bool owned:1;
                 } io;
                 struct {
                         sd_event_time_handler_t callback;
@@ -889,6 +890,10 @@ static void source_free(sd_event_source *s) {
         assert(s);
 
         source_disconnect(s);
+
+        if (s->type == SOURCE_IO && s->io.owned)
+                safe_close(s->io.fd);
+
         free(s->description);
         free(s);
 }
@@ -1494,6 +1499,21 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
         return 0;
 }
 
+_public_ int sd_event_source_get_io_fd_own(sd_event_source *s) {
+        assert_return(s, -EINVAL);
+        assert_return(s->type == SOURCE_IO, -EDOM);
+
+        return s->io.owned;
+}
+
+_public_ int sd_event_source_set_io_fd_own(sd_event_source *s, int own) {
+        assert_return(s, -EINVAL);
+        assert_return(s->type == SOURCE_IO, -EDOM);
+
+        s->io.owned = own;
+        return 0;
+}
+
 _public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
         assert_return(s, -EINVAL);
         assert_return(events, -EINVAL);
index 7b25d0c956f04956484c65c3e3c56953dbeecfe9..6b43315e90765796a6451b63c030ca5df88f5ff4 100644 (file)
@@ -127,6 +127,8 @@ int sd_event_source_get_enabled(sd_event_source *s, int *enabled);
 int sd_event_source_set_enabled(sd_event_source *s, int enabled);
 int sd_event_source_get_io_fd(sd_event_source *s);
 int sd_event_source_set_io_fd(sd_event_source *s, int fd);
+int sd_event_source_get_io_fd_own(sd_event_source *s);
+int sd_event_source_set_io_fd_own(sd_event_source *s, int own);
 int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events);
 int sd_event_source_set_io_events(sd_event_source *s, uint32_t events);
 int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents);