From b4de6f93aed733b8fc8d103e5ced69ebe7d659e6 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 9 Sep 2011 01:07:38 -0400 Subject: implement POSIX asynchronous io some features are not yet supported, and only minimal testing has been performed. should be considered experimental at this point. --- src/aio/aio_suspend.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/aio/aio_suspend.c (limited to 'src/aio/aio_suspend.c') diff --git a/src/aio/aio_suspend.c b/src/aio/aio_suspend.c new file mode 100644 index 00000000..cb2539e9 --- /dev/null +++ b/src/aio/aio_suspend.c @@ -0,0 +1,57 @@ +#include +#include +#include "pthread_impl.h" + +/* Due to the requirement that aio_suspend be async-signal-safe, we cannot + * use any locks, wait queues, etc. that would make it more efficient. The + * only obviously-correct algorithm is to generate a wakeup every time any + * aio operation finishes and have aio_suspend re-evaluate the completion + * status of each aiocb it was waiting on. */ + +static volatile int seq; + +void __aio_wake(void) +{ + a_inc(&seq); + __wake(&seq, -1, 1); +} + +int aio_suspend(struct aiocb *const cbs[], int cnt, const struct timespec *ts) +{ + int i, last, first=1, ret=0; + struct timespec at; + + if (cnt<0) { + errno = EINVAL; + return -1; + } + + for (;;) { + last = seq; + + for (i=0; i__err != EINPROGRESS) + return 0; + } + + if (first && ts) { + clock_gettime(CLOCK_MONOTONIC, &at); + at.tv_sec += ts->tv_sec; + if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) { + at.tv_nsec -= 1000000000; + at.tv_sec++; + } + first = 0; + } + + ret = __timedwait(&seq, last, CLOCK_MONOTONIC, + ts ? &at : 0, 0, 0, 1); + + if (ret == ETIMEDOUT) ret = EAGAIN; + + if (ret) { + errno = ret; + return -1; + } + } +} -- cgit v1.2.1