diff --git a/src/utils/channel.c b/src/utils/channel.c
index 92d793e468c441b044c24d76bedd2d9dc51510f0..c72953e956911b9e69ffc6ab44889283c5d319b7 100644 (file)
--- a/src/utils/channel.c
+++ b/src/utils/channel.c
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
#include "utils/channel.h"
#include <assert.h>
#include "utils/channel.h"
#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
size_t head;
size_t tail;
size_t head;
size_t tail;
- _Bool full;
+ bool full;
+
+ bool shutdown;
};
/*
};
/*
{
assert(chan);
{
assert(chan);
- if (chan->full)
+ if (chan->full || chan->shutdown)
return -1;
else if (! data)
return 0;
return -1;
else if (! data)
return 0;
sdb_channel_select(sdb_channel_t *chan, int *wantread, void *read_data,
int *wantwrite, void *write_data, const struct timespec *timeout)
{
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;
int status = 0;
- if (! chan)
+ if (! chan) {
+ errno = EINVAL;
return -1;
return -1;
+ }
- if ((! wantread) && (! read_data) && (! wantwrite) && (! write_data))
+ if ((! wantread) && (! read_data) && (! wantwrite) && (! write_data)) {
+ errno = EINVAL;
return -1;
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);
}
pthread_mutex_lock(&chan->lock);
break;
}
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);
status = pthread_cond_timedwait(&chan->cond, &chan->lock,
&abstime);
+ }
else
status = pthread_cond_wait(&chan->cond, &chan->lock);
}
else
status = pthread_cond_wait(&chan->cond, &chan->lock);
}
-
pthread_mutex_unlock(&chan->lock);
pthread_mutex_unlock(&chan->lock);
- return status;
+
+ if (status) {
+ errno = status;
+ return -1;
+ }
+ return 0;
} /* sdb_channel_select */
int
} /* sdb_channel_select */
int
return status;
} /* sdb_channel_read */
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 : */
/* vim: set tw=78 sw=4 ts=4 noexpandtab : */