asynchio(3)
NAME
asynchio, asyn_init, asyn_read, asyn_read, asyn_write, asyn_ioctl,
asyn_wait, asyn_synch - asynchronous I/O
SYNOPSIS
#include <fcntl.h>
#include <time.h>
#include <sys/asynchio.h>
void asyn_init(asynchio_t *asyn)
ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len)
ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len)
int asyn_ioctl(asynchio_t *asyn, int fd, ioreq_t request, void *data)
int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
int asyn_cancel(asynchio_t *asyn, int fd, int op)
int asyn_pending(asynchio_t *asyn, int fd, int op)
int asyn_synch(asynchio_t *asyn, int fd)
int asyn_close(asynchio_t *asyn, int fd)
DESCRIPTION
These routines make asynchronous I/O programming easier. Instead of
starting several operations (that may or may not succeed) and waiting for
them with fwait(2), one programs a loop around several asyn_read(),
asyn_write(), or asyn_ioctl() calls. One call to asyn_wait() blocks
waiting for one or more of the operations to succeed. Results are
returned by the I/O operations themselves, not by asyn_wait().
Asyn_init() initializes the bookkeeping structure needed to hold flags
and results. This call is not needed on globally allocated structures.
Asyn_read(), asyn_write(), asyn_ioctl() can be used just like the normal
read, write and ioctl system calls in asynchronous mode, except that you
can recall them until they return a result. The file descriptor flag
FD_ASYNCHIO is set on the first call.
Asyn_wait() uses fwait() to wait for one or more of the operations to
finish. It gathers all results that fwait has available before
returning. It will only block if all the operations are in progress, so
you will have to put a loop around everything. Use the ASYN_NONBLOCK
flag for a nonblocking call. This flag may or may not cause an error
return with errno set to EAGAIN. This depends on whether fwait was
actually called. This is how the routine works, either it simply returns
0 (no fwait called), or it will return like fwait. You can use a signal
to end the wait, or you can use a non-null to argument to specify a
timeout. (An absolute time, not a time difference.)
Asyn_synch() puts the file descriptor back into synchronous mode, and
removes it from the bookkeeping. It will fail with the EAGAIN error if
there is still an operation in progress.
Asyn_cancel() cancels a specific operation (use ASIO_READ, ASIO_WRITE or
ASIO_IOCTL for the operation code). With asyn_pending() one can check if
a result is available for a given operation. Use it after asyn_cancel()
to check if the cancel was too late, so that a result can still be
obtained with one of the asyn_read/write/ioctl calls. Asyn_pending()
returns 0 for no result, 1 for a result, and -1 for the unlikely case
that the file descriptor is invalid.
Asyn_close() only removes the bookkeeping on a file descriptor, the file
descriptor stays in asynchronous mode and there are no checks.
Example
This is how the functions may be used:
asynchio_t asyn;
asyn_init(&asyn);
len2= fill2(buf2);
while (1) {
if ((r= asyn_read(&asyn, fd1, buf1, len1)) != -1) {
use1(buf, r);
} else {
if (errno != EINPROGRESS) disaster1();
}
if ((r= asyn_write(&asyn, fd2, buf2, len2)) != -1) {
len2= fill2(buf2);
} else {
if (errno != EINPROGRESS) disaster2();
}
if (asyn_wait(&asyn, 0, NULL) == -1) {
if (errno == EINTR) timeout();
disaster3();
}
}
Typical "back to synch" code for a read operation:
if (asyn_cancel(&asyn, fd1, ASIO_READ) == -1) disaster4();
if (asyn_pending(&asyn, fd1, ASIO_READ)) {
r= asyn_read(&asyn, fd1, buf1, len1);
...
}
if (asyn_synch(&asyn, fd1) == -1) disaster5();
SEE ALSO
fwait(2), fcntl(2), read(2), write(2), ioctl(2).
AUTHOR
Kees J. Bot (kjb@cs.vu.nl)