X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Futils%2Fchannel.c;h=7c5c002ae545f43901e5b9dab352329936218b67;hp=afce6f5d9cc9aa883afb9569aef9a384c433eb01;hb=39a45905e0b237e458b1826ff9b4fad1c4a59550;hpb=23c8e0f818e5baf91e75993571b67fcb735628f5 diff --git a/src/utils/channel.c b/src/utils/channel.c index afce6f5..7c5c002 100644 --- a/src/utils/channel.c +++ b/src/utils/channel.c @@ -25,6 +25,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#if HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + #include "utils/channel.h" #include @@ -57,6 +61,8 @@ struct sdb_channel { size_t head; size_t tail; _Bool full; + + _Bool shutdown; }; /* @@ -79,7 +85,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; @@ -169,7 +175,6 @@ int sdb_channel_select(sdb_channel_t *chan, int *wantread, void *read_data, int *wantwrite, void *write_data, const struct timespec *timeout) { - struct timespec abstime; int status = 0; if (! chan) { @@ -182,14 +187,6 @@ sdb_channel_select(sdb_channel_t *chan, int *wantread, void *read_data, return -1; } - if (timeout) { - if (clock_gettime(CLOCK_REALTIME, &abstime)) - return -1; - - abstime.tv_sec += timeout->tv_sec; - abstime.tv_nsec += timeout->tv_nsec; - } - pthread_mutex_lock(&chan->lock); while (! status) { int read_status, write_status; @@ -208,14 +205,36 @@ sdb_channel_select(sdb_channel_t *chan, int *wantread, void *read_data, break; } - if (timeout) + if (chan->shutdown) { + if (read_status) + status = EBADF; + break; + } + + if (timeout) { + struct timespec abstime; + + if (clock_gettime(CLOCK_REALTIME, &abstime)) { + pthread_mutex_unlock(&chan->lock); + return -1; + } + + abstime.tv_sec += timeout->tv_sec; + abstime.tv_nsec += timeout->tv_nsec; + + if (abstime.tv_nsec > 1000000000) { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec += 1; + } + status = pthread_cond_timedwait(&chan->cond, &chan->lock, &abstime); + } else status = pthread_cond_wait(&chan->cond, &chan->lock); } - pthread_mutex_unlock(&chan->lock); + if (status) { errno = status; return -1; @@ -251,5 +270,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 : */