Code

utils channel: Added sdb_channel_shutdown().
authorSebastian Harl <sh@tokkee.org>
Mon, 21 Oct 2013 07:10:08 +0000 (09:10 +0200)
committerSebastian Harl <sh@tokkee.org>
Mon, 21 Oct 2013 07:10:08 +0000 (09:10 +0200)
This function initiates a shutdown of the channel, forbidding any subsequent
writes. However, readers are still able to empty the buffer. Then, EBADF will
be returned through errno. This allows for graceful shutdowns.

src/include/utils/channel.h
src/utils/channel.c

index e1b3f0e63e695f83b4ebf5d64671bf181920ff2f..49d37fdcfec6ec6d87df83697a382fa243b48575 100644 (file)
@@ -108,6 +108,18 @@ int
 sdb_channel_select(sdb_channel_t *chan, int *wantread, void *read_data,
                int *wantwrite, void *write_data, const struct timespec *timeout);
 
+/* sdb_channel_shutdown:
+ * Initiate a shutdown of the channel. Any subsequent writes will fail. Read
+ * operations will still be possible until the channel buffer is empty and
+ * then fail as well. Failing operations set errno to EBADF.
+ *
+ * Returns:
+ *  - 0 on success
+ *  - a negative value else
+ */
+int
+sdb_channel_shutdown(sdb_channel_t *chan);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 8e55ae564872f1052494f78ddd62658b40d48394..a45247a71060503b55589655e2cd6711dd1bcd7f 100644 (file)
@@ -57,6 +57,8 @@ struct sdb_channel {
        size_t head;
        size_t tail;
        _Bool full;
+
+       _Bool shutdown;
 };
 
 /*
@@ -79,7 +81,7 @@ channel_write(sdb_channel_t *chan, const void *data)
 {
        assert(chan);
 
-       if (chan->full)
+       if (chan->full || chan->shutdown)
                return -1;
        else if (! data)
                return 0;
@@ -199,6 +201,12 @@ sdb_channel_select(sdb_channel_t *chan, int *wantread, void *read_data,
                                break;
                }
 
+               if (chan->shutdown) {
+                       if (read_status)
+                               status = EBADF;
+                       break;
+               }
+
                if (timeout) {
                        struct timespec abstime;
 
@@ -258,5 +266,14 @@ sdb_channel_read(sdb_channel_t *chan, void *data)
        return status;
 } /* sdb_channel_read */
 
+int
+sdb_channel_shutdown(sdb_channel_t *chan)
+{
+       if (! chan)
+               return -1;
+       chan->shutdown = 1;
+       return 0;
+} /* sdb_channel_shutdown */
+
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */