IO-AIO
view release on metacpan or search on metacpan
While request submission and execution is fully asynchronous, result
processing is not and relies on the perl interpreter calling C<poll_cb>
(or another function with the same effect).
=item result
The request results are processed synchronously by C<poll_cb>.
The C<poll_cb> function will process all outstanding aio requests by
calling their callbacks, freeing memory associated with them and managing
any groups they are contained in.
=item done
Request has reached the end of its lifetime and holds no resources anymore
(except possibly for the Perl object, but its connection to the actual
aio request is severed and calling its methods will either do nothing or
result in a runtime error).
=back
=cut
package IO::AIO;
use Carp ();
use common::sense;
use base 'Exporter';
BEGIN {
our $VERSION = 4.81;
our @AIO_REQ = qw(aio_sendfile aio_seek aio_read aio_write aio_open aio_close
aio_stat aio_lstat aio_unlink aio_rmdir aio_readdir aio_readdirx
aio_scandir aio_symlink aio_readlink aio_realpath aio_fcntl aio_ioctl
aio_sync aio_fsync aio_syncfs aio_fdatasync aio_sync_file_range
aio_pathsync aio_readahead aio_fiemap aio_allocate
aio_rename aio_rename2 aio_link aio_move aio_copy aio_group
aio_nop aio_mknod aio_load aio_rmtree aio_mkdir aio_chown
aio_chmod aio_utime aio_truncate
aio_msync aio_mtouch aio_mlock aio_mlockall
aio_statvfs
aio_slurp
aio_wd);
our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice));
our @EXPORT_OK = qw(poll_fileno poll_cb poll_wait flush
min_parallel max_parallel max_idle idle_timeout
nreqs nready npending nthreads
max_poll_time max_poll_reqs
sendfile fadvise madvise
mmap munmap mremap munlock munlockall
accept4 tee splice pipe2 pipesize
fexecve mount umount memfd_create eventfd
timerfd_create timerfd_settime timerfd_gettime
pidfd_open pidfd_send_signal pidfd_getfd);
push @AIO_REQ, qw(aio_busy); # not exported
@IO::AIO::GRP::ISA = 'IO::AIO::REQ';
require XSLoader;
XSLoader::load ("IO::AIO", $VERSION);
}
=head1 FUNCTIONS
=head2 QUICK OVERVIEW
This section simply lists the prototypes most of the functions for
quick reference. See the following sections for function-by-function
documentation.
aio_wd $pathname, $callback->($wd)
aio_open $pathname, $flags, $mode, $callback->($fh)
aio_close $fh, $callback->($status)
aio_seek $fh,$offset,$whence, $callback->($offs)
aio_read $fh,$offset,$length, $data,$dataoffset, $callback->($retval)
aio_write $fh,$offset,$length, $data,$dataoffset, $callback->($retval)
aio_sendfile $out_fh, $in_fh, $in_offset, $length, $callback->($retval)
aio_readahead $fh,$offset,$length, $callback->($retval)
aio_stat $fh_or_path, $callback->($status)
aio_lstat $fh, $callback->($status)
aio_statvfs $fh_or_path, $callback->($statvfs)
aio_utime $fh_or_path, $atime, $mtime, $callback->($status)
aio_chown $fh_or_path, $uid, $gid, $callback->($status)
aio_chmod $fh_or_path, $mode, $callback->($status)
aio_truncate $fh_or_path, $offset, $callback->($status)
aio_allocate $fh, $mode, $offset, $len, $callback->($status)
aio_fiemap $fh, $start, $length, $flags, $count, $cb->(\@extents)
aio_unlink $pathname, $callback->($status)
aio_mknod $pathname, $mode, $dev, $callback->($status)
aio_link $srcpath, $dstpath, $callback->($status)
aio_symlink $srcpath, $dstpath, $callback->($status)
aio_readlink $pathname, $callback->($link)
aio_realpath $pathname, $callback->($path)
aio_rename $srcpath, $dstpath, $callback->($status)
aio_rename2 $srcpath, $dstpath, $flags, $callback->($status)
aio_mkdir $pathname, $mode, $callback->($status)
aio_rmdir $pathname, $callback->($status)
aio_readdir $pathname, $callback->($entries)
aio_readdirx $pathname, $flags, $callback->($entries, $flags)
IO::AIO::READDIR_DENTS IO::AIO::READDIR_DIRS_FIRST
IO::AIO::READDIR_STAT_ORDER IO::AIO::READDIR_FOUND_UNKNOWN
aio_scandir $pathname, $maxreq, $callback->($dirs, $nondirs)
aio_load $pathname, $data, $callback->($status)
aio_copy $srcpath, $dstpath, $callback->($status)
aio_move $srcpath, $dstpath, $callback->($status)
aio_rmtree $pathname, $callback->($status)
aio_fcntl $fh, $cmd, $arg, $callback->($status)
aio_ioctl $fh, $request, $buf, $callback->($status)
aio_sync $callback->($status)
aio_syncfs $fh, $callback->($status)
aio_fsync $fh, $callback->($status)
aio_fdatasync $fh, $callback->($status)
aio_sync_file_range $fh, $offset, $nbytes, $flags, $callback->($status)
aio_pathsync $pathname, $callback->($status)
aio_msync $scalar, $offset = 0, $length = undef, flags = MS_SYNC, $callback->($status)
If an error occurs, the callback receives no arguments. The special
C<errno> value C<IO::AIO::EBADR> is available to test for flag errors.
Otherwise, the callback receives an array reference with extent
structures. Each extent structure is an array reference itself, with the
following members:
[$logical, $physical, $length, $flags]
Flags is any combination of the following flag values (typically either C<0>
or C<IO::AIO::FIEMAP_EXTENT_LAST> (1)):
C<IO::AIO::FIEMAP_EXTENT_LAST>, C<IO::AIO::FIEMAP_EXTENT_UNKNOWN>,
C<IO::AIO::FIEMAP_EXTENT_DELALLOC>, C<IO::AIO::FIEMAP_EXTENT_ENCODED>,
C<IO::AIO::FIEMAP_EXTENT_DATA_ENCRYPTED>, C<IO::AIO::FIEMAP_EXTENT_NOT_ALIGNED>,
C<IO::AIO::FIEMAP_EXTENT_DATA_INLINE>, C<IO::AIO::FIEMAP_EXTENT_DATA_TAIL>,
C<IO::AIO::FIEMAP_EXTENT_UNWRITTEN>, C<IO::AIO::FIEMAP_EXTENT_MERGED> or
C<IO::AIO::FIEMAP_EXTENT_SHARED>.
At the time of this writing (Linux 3.2), this request is unreliable unless
C<$count> is C<undef>, as the kernel has all sorts of bugs preventing
it to return all extents of a range for files with a large number of
extents. The code (only) works around all these issues if C<$count> is
C<undef>.
=item aio_group $callback->(...)
This is a very special aio request: Instead of doing something, it is a
container for other aio requests, which is useful if you want to bundle
many requests into a single, composite, request with a definite callback
and the ability to cancel the whole request with its subrequests.
Returns an object of class L<IO::AIO::GRP>. See its documentation below
for more info.
Example:
my $grp = aio_group sub {
print "all stats done\n";
};
add $grp
(aio_stat ...),
(aio_stat ...),
...;
=item aio_nop $callback->()
This is a special request - it does nothing in itself and is only used for
side effects, such as when you want to add a dummy request to a group so
that finishing the requests in the group depends on executing the given
code.
While this request does nothing, it still goes through the execution
phase and still requires a worker thread. Thus, the callback will not
be executed immediately but only after other requests in the queue have
entered their execution phase. This can be used to measure request
latency.
=item IO::AIO::aio_busy $fractional_seconds, $callback->() *NOT EXPORTED*
Mainly used for debugging and benchmarking, this aio request puts one of
the request workers to sleep for the given time.
While it is theoretically handy to have simple I/O scheduling requests
like sleep and file handle readable/writable, the overhead this creates is
immense (it blocks a thread for a long time) so do not use this function
except to put your application under artificial I/O pressure.
=back
=head2 IO::AIO::WD - multiple working directories
Your process only has one current working directory, which is used by all
threads. This makes it hard to use relative paths (some other component
could call C<chdir> at any time, and it is hard to control when the path
will be used by IO::AIO).
One solution for this is to always use absolute paths. This usually works,
but can be quite slow (the kernel has to walk the whole path on every
access), and can also be a hassle to implement.
Newer POSIX systems have a number of functions (openat, fdopendir,
futimensat and so on) that make it possible to specify working directories
per operation.
For portability, and because the clowns who "designed", or shall I write,
perpetrated this new interface were obviously half-drunk, this abstraction
cannot be perfect, though.
IO::AIO allows you to convert directory paths into a so-called IO::AIO::WD
object. This object stores the canonicalised, absolute version of the
path, and on systems that allow it, also a directory file descriptor.
Everywhere where a pathname is accepted by IO::AIO (e.g. in C<aio_stat>
or C<aio_unlink>), one can specify an array reference with an IO::AIO::WD
object and a pathname instead (or the IO::AIO::WD object alone, which
gets interpreted as C<[$wd, "."]>). If the pathname is absolute, the
IO::AIO::WD object is ignored, otherwise the pathname is resolved relative
to that IO::AIO::WD object.
For example, to get a wd object for F</etc> and then stat F<passwd>
inside, you would write:
aio_wd "/etc", sub {
my $etcdir = shift;
# although $etcdir can be undef on error, there is generally no reason
# to check for errors here, as aio_stat will fail with ENOENT
# when $etcdir is undef.
aio_stat [$etcdir, "passwd"], sub {
# yay
};
};
The fact that C<aio_wd> is a request and not a normal function shows that
creating an IO::AIO::WD object is itself a potentially blocking operation,
which is why it is done asynchronously.
( run in 1.866 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )