--- Linux-AIO/AIO.pm 2004/07/18 10:58:00 1.18 +++ Linux-AIO/AIO.pm 2006/02/01 23:47:26 1.37 @@ -6,12 +6,18 @@ use Linux::AIO; + # This module has been mostly superseded by IO::AIO. + =head1 DESCRIPTION -This module implements asynchronous i/o using the means available to linux -- clone. It does not hook into the POSIX aio_* functions because linux -does not yet support these in the kernel (and even if, it would only allow -aio_read and write, not open and stat). +I + +This module implements asynchronous I/O using the means available to Linux +- clone. It does not hook into the POSIX aio_* functions because Linux +does not yet support these in the kernel (even as of 2.6.12, only O_DIRECT +files are supported) and even if, it would only allow aio_read and write, +not open, stat and so on. Instead, in this module a number of (non-posix) threads are started that execute your read/writes and signal their completion. You don't need @@ -22,8 +28,25 @@ when the thread calling min_parallel exits. Make sure you only ever call min_parallel from the same thread that loaded this module. -Although the module will work with threads, it is not reentrant, so use -appropriate locking yourself. +Although the module will work with in the presence of other threads, it is +not reentrant, so use appropriate locking yourself. + +=head2 API NOTES + +All the C calls are more or less thin wrappers around the syscall +with the same name (sans C). The arguments are similar or identical, +and they all accept an additional C<$callback> argument which must be +a code reference. This code reference will get called with the syscall +return code (e.g. most syscalls return C<-1> on error, unlike perl, which +usually delivers "false") as it's sole argument when the given syscall has +been executed asynchronously. + +All functions that expect a filehandle will also accept a file descriptor. + +The filenames you pass to these routines I be absolute. The reason +is that at the time the request is being executed, the current working +directory could have changed. Alternatively, you can make sure that you +never change the current working directory. =over 4 @@ -34,9 +57,10 @@ use base 'Exporter'; BEGIN { - $VERSION = 1.2; + $VERSION = 1.9; - @EXPORT = qw(aio_read aio_write aio_open aio_close aio_stat aio_lstat aio_unlink); + @EXPORT = qw(aio_read aio_write aio_open aio_close aio_stat aio_lstat aio_unlink + aio_fsync aio_fdatasync aio_readahead); @EXPORT_OK = qw(poll_fileno poll_cb min_parallel max_parallel nreqs); require XSLoader; @@ -49,10 +73,24 @@ C<1>, which means a single asynchronous operation can be done at one time (the number of outstanding operations, however, is unlimited). -It is recommended to keep the number of threads low, as many linux +It is recommended to keep the number of threads low, as some linux kernel versions will scale negatively with the number of threads (higher parallelity => MUCH higher latency). +Under normal circumstances you don't need to call this function, as this +module automatically starts a single async thread. + +=item Linux::AIO::max_parallel $nthreads + +Sets the maximum number of AIO threads to C<$nthreads>. If more than +the specified number of threads are currently running, kill them. This +function blocks until the limit is reached. + +This module automatically runs C at program end, to ensure +that all threads are killed and that there are no outstanding requests. + +Under normal circumstances you don't need to call this function. + =item $fileno = Linux::AIO::poll_fileno Return the I. This filehandle must be @@ -60,6 +98,8 @@ or select, see below). If the pipe becomes readable you have to call C to check the results. +See C for an example. + =item Linux::AIO::poll_cb Process all outstanding events on the result pipe. You have to call this @@ -70,19 +110,49 @@ Event->io (fd => Linux::AIO::poll_fileno, poll => 'r', async => 1, - cb => \&Linux::AIO::poll_cb ); + cb => \&Linux::AIO::poll_cb); + +=item Linux::AIO::poll_wait +Wait till the result filehandle becomes ready for reading (simply does a +select on the filehandle. This is useful if you want to synchronously wait +for some requests to finish). + +See C for an example. =item Linux::AIO::nreqs Returns the number of requests currently outstanding. -=item aio_open $pathname, $flags, $mode, $callback +Example: wait till there are no outstanding requests anymore: + + Linux::AIO::poll_wait, Linux::AIO::poll_cb + while Linux::AIO::nreqs; + +=item aio_open $pathname, $flags, $mode, $callback Asynchronously open or create a file and call the callback with the filedescriptor (NOT a perl filehandle, sorry for that, but watch out, this might change in the future). +The pathname passed to C must be absolute. See API NOTES, above, +for an explanation. + +The C<$mode> argument is a bitmask. See the C module for a +list. They are the same as used in C. + +Example: + + aio_open "/etc/passwd", O_RDONLY, 0, sub { + if ($_[0] >= 0) { + open my $fh, "<&=$_[0]"; + print "open successful, fh is $fh\n"; + ... + } else { + die "open failed: $!\n"; + } + }; + =item aio_close $fh, $callback Asynchronously close a file and call the callback with the result code. @@ -93,7 +163,30 @@ Reads or writes C bytes from the specified C and C into the scalar given by C and offset C and calls the -callback without the actual number of bytes read (or C on error). +callback without the actual number of bytes read (or -1 on error, just +like the syscall). + +Example: Read 15 bytes at offset 7 into scalar C<$buffer>, strating at +offset C<0> within the scalar: + + aio_read $fh, 7, 15, $buffer, 0, sub { + $_[0] >= 0 or die "read error: $!"; + print "read <$buffer>\n"; + }; + +=item aio_readahead $fh,$offset,$length, $callback + +Asynchronously reads the specified byte range into the page cache, using +the C syscall. + +readahead() populates the page cache with data from a file so that +subsequent reads from that file will not block on disk I/O. The C<$offset> +argument specifies the starting point from which data is to be read and +C<$length> specifies the number of bytes to be read. I/O is performed in +whole pages, so that offset is effectively rounded down to a page boundary +and bytes are read up to the next page boundary greater than or equal to +(off-set+length). aio_readahead() does not read beyond the end of the +file. The current file offset of the file is left unchanged. =item aio_stat $fh_or_path, $callback @@ -103,13 +196,34 @@ be called after the stat and the results will be available using C or C<-s _> etc... +The pathname passed to C must be absolute. See API NOTES, above, +for an explanation. + Currently, the stats are always 64-bit-stats, i.e. instead of returning an error when stat'ing a large file, the results will be silently truncated unless perl itself is compiled with large file support. -=item aio_unlink $pathname, $callback +Example: Print the length of F: + + aio_stat "/etc/passwd", sub { + $_[0] and die "stat failed: $!"; + print "size is ", -s _, "\n"; + }; + +=item aio_unlink $pathname, $callback + +Asynchronously unlink (delete) a file and call the callback with the +result code. + +=item aio_fsync $fh, $callback + +Asynchronously call fsync on the given filehandle and call the callback +with the fsync result code. + +=item aio_fdatasync $fh, $callback -Asynchronously unlink a file. +Asynchronously call fdatasync on the given filehandle and call the +callback with the fdatasync result code. =cut @@ -132,12 +246,12 @@ =head1 SEE ALSO -L. +L, L. =head1 AUTHOR - Marc Lehmann - http://www.goof.com/pcg/marc/ + Marc Lehmann + http://home.schmorp.de/ =cut