--- IO-AIO/AIO.pm 2006/10/28 01:40:30 1.85 +++ IO-AIO/AIO.pm 2006/10/28 23:32:29 1.86 @@ -84,6 +84,50 @@ locking yourself, always call C from within the same thread, or never call C (or other C functions) recursively. +=head2 EXAMPLE + +This is a simple example that uses the Event module and loads +F asynchronously: + + use Fcntl; + use Event; + use IO::AIO; + + # register the IO::AIO callback with Event + Event->io (fd => IO::AIO::poll_fileno, + poll => 'r', + cb => \&IO::AIO::poll_cb); + + # queue the request to open /etc/passwd + aio_open "/etc/passwd", O_RDONLY, 0, sub { + my $fh = $_[0] + or die "error while opening: $!"; + + # stat'ing filehandles is generally non-blocking + my $size = -s $fh; + + # queue a request to read the file + my $contents; + aio_read $fh, 0, $size, $contents, 0, sub { + $_[0] == $size + or die "short read: $!"; + + close $fh; + + # file contents now in $contents + print $contents; + + # exit event loop and program + Event::unloop; + }; + }; + + # possibly queue up other requests, or open GUI windows, + # check for sockets etc. etc. + + # process events as long as there are some: + Event::loop; + =head1 REQUEST ANATOMY AND LIFETIME Every C function creates a request. which is a C data structure not @@ -144,7 +188,7 @@ use base 'Exporter'; BEGIN { - our $VERSION = '2.0'; + our $VERSION = '2.1'; 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 @@ -152,7 +196,9 @@ aio_copy aio_group aio_nop aio_mknod); our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice)); our @EXPORT_OK = qw(poll_fileno poll_cb poll_wait flush - min_parallel max_parallel nreqs nready npending); + min_parallel max_parallel max_idle + nreqs nready npending nthreads + max_poll_time max_poll_reqs); @IO::AIO::GRP::ISA = 'IO::AIO::REQ'; @@ -349,9 +395,11 @@ =item aio_mknod $path, $mode, $dev, $callback->($status) +[EXPERIMENTAL] + Asynchronously create a device node (or fifo). See mknod(2). -The only portable (POSIX) way of calling this function is: +The only (POSIX-) portable way of calling this function is: aio_mknod $path, IO::AIO::S_IFIFO | $mode, 0, sub { ... @@ -847,6 +895,8 @@ =head2 SUPPORT FUNCTIONS +=head3 EVENT PROCESSING AND EVENT LOOP INTEGRATION + =over 4 =item $fileno = IO::AIO::poll_fileno @@ -860,9 +910,10 @@ =item IO::AIO::poll_cb -Process all outstanding events on the result pipe. You have to call this +Process some outstanding events on the result pipe. You have to call this regularly. Returns the number of events processed. Returns immediately -when no events are outstanding. +when no events are outstanding. The amount of events processed depends on +the settings of C and C. If not all requests were processed for whatever reason, the filehandle will still be ready when C returns. @@ -874,49 +925,50 @@ poll => 'r', async => 1, cb => \&IO::AIO::poll_cb); -=item IO::AIO::poll_some $max_requests +=item IO::AIO::max_poll_reqs $nreqs + +=item IO::AIO::max_poll_time $seconds + +These set the maximum number of requests (default C<0>, meaning infinity) +that are being processed by C in one call, respectively +the maximum amount of time (default C<0>, meaning infinity) spent in +C to process requests (more correctly the mininum amount +of time C is allowed to use). -Similar to C, but only processes up to C<$max_requests> requests -at a time. +Setting these is useful if you want to ensure some level of +interactiveness when perl is not fast enough to process all requests in +time. -Useful if you want to ensure some level of interactiveness when perl is -not fast enough to process all requests in time. +For interactive programs, values such as C<0.01> to C<0.1> should be fine. Example: Install an Event watcher that automatically calls IO::AIO::poll_some with low priority, to ensure that other parts of the program get the CPU sometimes even under high AIO load. + # try not to spend much more than 0.1s in poll_cb + IO::AIO::max_poll_time 0.1; + + # use a low priority so other tasks have priority Event->io (fd => IO::AIO::poll_fileno, poll => 'r', nice => 1, - cb => sub { IO::AIO::poll_some 256 }); + cb => &IO::AIO::poll_cb); =item IO::AIO::poll_wait Wait till the result filehandle becomes ready for reading (simply does a -C on the filehandle. This is useful if you want to synchronously +wait for some requests to finish). See C for an example. -=item IO::AIO::nreqs +=item IO::AIO::poll -Returns the number of requests currently in the ready, execute or pending -states (i.e. for which their callback has not been invoked yet). +Waits until some requests have been handled. -Example: wait till there are no outstanding requests anymore: +Strictly equivalent to: IO::AIO::poll_wait, IO::AIO::poll_cb - while IO::AIO::nreqs; - -=item IO::AIO::nready - -Returns the number of requests currently in the ready state (not yet -executed). - -=item IO::AIO::npending - -Returns the number of requests currently in the pending state (executed, -but not yet processed by poll_cb). + if IO::AIO::nreqs; =item IO::AIO::flush @@ -927,14 +979,7 @@ IO::AIO::poll_wait, IO::AIO::poll_cb while IO::AIO::nreqs; -=item IO::AIO::poll - -Waits until some requests have been handled. - -Strictly equivalent to: - - IO::AIO::poll_wait, IO::AIO::poll_cb - if IO::AIO::nreqs; +=head3 CONTROLLING THE NUMBER OF THREADS =item IO::AIO::min_parallel $nthreads @@ -944,7 +989,9 @@ however, is unlimited). IO::AIO starts threads only on demand, when an AIO request is queued and -no free thread exists. +no free thread exists. Please note that queueing up a hundred requests can +create demand for a hundred threads, even if it turns out that everything +is in the cache and could have been processed faster by a single thread. It is recommended to keep the number of threads relatively low, as some Linux kernel versions will scale negatively with the number of threads @@ -968,6 +1015,21 @@ Under normal circumstances you don't need to call this function. +=item IO::AIO::max_idle $nthreads + +Limit the number of threads (default: 4) that are allowed to idle (i.e., +threads that did not get a request to process within 10 seconds). That +means if a thread becomes idle while C<$nthreads> other threads are also +idle, it will free its resources and exit. + +This is useful when you allow a large number of threads (e.g. 100 or 1000) +to allow for extremely high load situations, but want to free resources +under normal circumstances (1000 threads can easily consume 30MB of RAM). + +The default is probably ok in most situations, especially if thread +creation is fast. If thread creation is very slow on your system you might +want to use larger values. + =item $oldmaxreqs = IO::AIO::max_outstanding $maxreqs This is a very bad function to use in interactive programs because it @@ -986,6 +1048,28 @@ C is mainly useful in simple scripts (with low values) or as a stop gap to shield against fatal memory overflow (with large values). +=head3 STATISTICAL INFORMATION + +=item IO::AIO::nreqs + +Returns the number of requests currently in the ready, execute or pending +states (i.e. for which their callback has not been invoked yet). + +Example: wait till there are no outstanding requests anymore: + + IO::AIO::poll_wait, IO::AIO::poll_cb + while IO::AIO::nreqs; + +=item IO::AIO::nready + +Returns the number of requests currently in the ready state (not yet +executed). + +=item IO::AIO::npending + +Returns the number of requests currently in the pending state (executed, +but not yet processed by poll_cb). + =back =cut