Coro::AIO - truly asynchronous file and directrory I/O


   use Coro::AIO;

   # can now use any of the aio requests your IO::AIO module supports.

   # read 1MB of /etc/passwd, without blocking other coroutines
   my $fh = aio_open "/etc/passwd", O_RDONLY, 0
      or die "/etc/passwd: $!";
   aio_read $fh, 0, 1_000_000, my $buf, 0
      or die "aio_read: $!";
   aio_close $fh;


This module implements a thin wrapper around IO::AIO. All of the functions that expect a callback are being wrapped by this module.

The API is exactly the same as that of the corresponding IO::AIO routines, except that you have to specify all arguments except the callback argument. Instead the routines return the values normally passed to the callback. Everything else, including $! and perls stat cache, are set as expected after these functions return.

You can mix calls to IO::AIO functions with calls to this module. You must not, however, call these routines from within IO::AIO callbacks, as this causes a deadlock. Start a coro inside the callback instead.

You also can, but do not need to, call IO::AIO::poll_cb, as this module automatically installs an event watcher for the IO::AIO file descriptor. It uses the AnyEvent module for this, so please refer to its documentation on how it selects an appropriate Event module.

All other functions exported by default by IO::AIO (e.g. aioreq_pri) will be exported by default by Coro::AIO, too.

Functions that can be optionally imported from IO::AIO can be imported from Coro::AIO or can be called directly, e.g. Coro::AIO::nreqs.

You cannot specify priorities with aioreq_pri, as this module overwrites the request priority with the current coroutine priority at all times.

For your convienience, here are the changed function signatures for most of the requests, for documentation of these functions please have a look at IO::AIO.

The AnyEvent watcher can be disabled by executing undef $Coro::AIO::WATCHER. Please notify the author of when and why you think this was necessary.

$fh = aio_open $pathname, $flags, $mode
$status = aio_close $fh
$retval = aio_read $fh,$offset,$length, $data,$dataoffset
$retval = aio_write $fh,$offset,$length, $data,$dataoffset
$retval = aio_sendfile $out_fh, $in_fh, $in_offset, $length
$retval = aio_readahead $fh,$offset,$length
$status = aio_stat $fh_or_path
$status = aio_lstat $fh
$status = aio_rmdir $pathname
$entries = aio_readdir $pathname
($dirs, $nondirs) = aio_scandir $path, $maxreq
$status = aio_fsync $fh
$status = aio_fdatasync $fh
... = aio_xxx ...

Any additional aio requests follow the same scheme: same parameters except you must not specify a callback but instead get the callback arguments as return values.


Coro::Socket and Coro::Handle for non-blocking socket operation.


 Marc Lehmann <>