From cd2c02cefddee94e0142a8f1d3d156c05c58472a Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Mon, 21 Oct 2013 09:10:08 +0200 Subject: [PATCH] utils channel: Added sdb_channel_shutdown(). 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 | 12 ++++++++++++ src/utils/channel.c | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/include/utils/channel.h b/src/include/utils/channel.h index e1b3f0e..49d37fd 100644 --- a/src/include/utils/channel.h +++ b/src/include/utils/channel.h @@ -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 diff --git a/src/utils/channel.c b/src/utils/channel.c index 8e55ae5..a45247a 100644 --- a/src/utils/channel.c +++ b/src/utils/channel.c @@ -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 : */ -- 2.30.2