--- IO-AIO/AIO.pm 2006/10/23 00:34:36 1.63 +++ IO-AIO/AIO.pm 2006/10/24 03:40:38 1.70 @@ -20,6 +20,7 @@ # version 2+ has request and group objects use IO::AIO 2; + aioreq_pri 4; # give next request a very high priority my $req = aio_unlink "/tmp/file", sub { }; $req->cancel; # cancel request if still in queue @@ -53,18 +54,18 @@ operating system supports. Currently, a number of threads are started that execute your read/writes -and signal their completion. You don't need thread support in your libc or -perl, and the threads created by this module will not be visible to the -pthreads library. In the future, this module might make use of the native -aio functions available on many operating systems. However, they are often -not well-supported (Linux doesn't allow them on normal files currently, -for example), and they would only support aio_read and aio_write, so the -remaining functionality would have to be implemented using threads anyway. - -Although the module will work with in the presence of other threads, it is -currently not reentrant, so use appropriate locking yourself, always call -C from within the same thread, or never call C (or other -C functions) recursively. +and signal their completion. You don't need thread support in perl, and +the threads created by this module will not be visible to perl. In the +future, this module might make use of the native aio functions available +on many operating systems. However, they are often not well-supported +(Linux doesn't allow them on normal files currently, for example), +and they would only support aio_read and aio_write, so the remaining +functionality would have to be implemented using threads anyway. + +Although the module will work with in the presence of other threads, +it is currently not reentrant in any way, so use appropriate locking +yourself, always call C from within the same thread, or never +call C (or other C functions) recursively. =cut @@ -78,11 +79,13 @@ BEGIN { our $VERSION = '2.0'; - our @EXPORT = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat - aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink - aio_fsync aio_fdatasync aio_readahead aio_rename aio_link aio_move - aio_group aio_nop); - our @EXPORT_OK = qw(poll_fileno poll_cb min_parallel max_parallel max_outstanding nreqs); + our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat + aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink + aio_fsync aio_fdatasync aio_readahead aio_rename aio_link aio_move + aio_group aio_nop); + 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_outstanding nreqs); @IO::AIO::GRP::ISA = 'IO::AIO::REQ'; @@ -123,6 +126,34 @@ =over 4 +=item aioreq_pri $pri + +Sets the priority for the next aio request. The default priority +is C<0>, the minimum and maximum priorities are C<-4> and C<4>, +respectively. Requests with higher priority will be serviced first. + +The priority will be reset to C<0> after each call to one of the C +functions. + +Example: open a file with low priority, then read something from it with +higher priority so the read request is serviced before other low priority +open requests (potentially spamming the cache): + + aioreq_pri -3; + aio_open ..., sub { + return unless $_[0]; + + aioreq_pri -2; + aio_read $_[0], ..., sub { + ... + }; + }; + +=item aioreq_nice $pri_adjust + +Similar to C, but subtracts the given value from the current +priority, so effects are cumulative. + =item aio_open $pathname, $flags, $mode, $callback->($fh) Asynchronously open or create a file and call the callback with a newly @@ -542,6 +573,12 @@ 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_sleep $fractional_seconds, $callback->() *NOT EXPORTED* Mainly used for debugging and benchmarking, this aio request puts one of @@ -569,7 +606,7 @@ =over 4 -=item $req->cancel +=item cancel $req Cancels the request, if possible. Has the effect of skipping execution when entering the B state and skipping calling the callback when @@ -577,6 +614,10 @@ untouched. That means that requests that currently execute will not be stopped and resources held by the request will not be freed prematurely. +=item cb $req $callback->(...) + +Replace (or simply set) the callback registered to the request. + =back =head2 IO::AIO::GRP CLASS @@ -643,10 +684,10 @@ =over 4 -=item $grp->add (...) - =item add $grp ... +=item $grp->add (...) + Add one or more requests to the group. Any type of L can be added, including other groups, as long as you do not create circular dependencies. @@ -658,7 +699,7 @@ Set the result value(s) that will be passed to the group callback when all subrequests have finished. By default, no argument will be passed. -=item $grp->set_feeder ($callback->($grp)) +=item feed $grp $callback->($grp) [VERY EXPERIMENTAL] @@ -671,32 +712,32 @@ To avoid this, and allow incremental generation of requests, you can instead a group and set a feeder on it that generates those requests. The -feeder will be called whenever there are few enough (see C, +feed callback will be called whenever there are few enough (see C, below) requests active in the group itself and is expected to queue more requests. -The feeder can queue as many requests as it likes (i.e. C does not -impose any limits). +The feed callback can queue as many requests as it likes (i.e. C does +not impose any limits). -If the feeder does not queue more requests when called, it will be +If the feed does not queue more requests when called, it will be automatically removed from the group. -If the feeder limit is C<0>, it will be set to C<2> automatically. +If the feed limit is C<0>, it will be set to C<2> automatically. Example: # stat all files in @files, but only ever use four aio requests concurrently: my $grp = aio_group sub { print "finished\n" }; - $grp->feeder_limit (4); - $grp->set_feeder (sub { + limit $grp 4; + feed $grp sub { my $file = pop @files or return; add $grp aio_stat $file, sub { ... }; - }); + }; -=item $grp->feeder_limit ($num) +=item limit $grp $num Sets the feeder limit for the group: The feeder will be called whenever the group contains less than this many requests. @@ -876,7 +917,7 @@ =head1 SEE ALSO -L, L (obsolete). +L. =head1 AUTHOR