ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/IO-AIO/AIO.pm
(Generate patch)

Comparing IO-AIO/AIO.pm (file contents):
Revision 1.209 by root, Tue Sep 27 00:41:51 2011 UTC vs.
Revision 1.213 by root, Thu Sep 29 23:06:23 2011 UTC

281=head2 AIO REQUEST FUNCTIONS 281=head2 AIO REQUEST FUNCTIONS
282 282
283All the C<aio_*> calls are more or less thin wrappers around the syscall 283All the C<aio_*> calls are more or less thin wrappers around the syscall
284with the same name (sans C<aio_>). The arguments are similar or identical, 284with the same name (sans C<aio_>). The arguments are similar or identical,
285and they all accept an additional (and optional) C<$callback> argument 285and they all accept an additional (and optional) C<$callback> argument
286which must be a code reference. This code reference will get called with 286which must be a code reference. This code reference will be called after
287the syscall return code (e.g. most syscalls return C<-1> on error, unlike 287the syscall has been executed in an asynchronous fashion. The results
288perl, which usually delivers "false") as its sole argument after the given 288of the request will be passed as arguments to the callback (and, if an
289syscall has been executed asynchronously. 289error occured, in C<$!>) - for most requests the syscall return code (e.g.
290most syscalls return C<-1> on error, unlike perl, which usually delivers
291"false").
292
293Some requests (such as C<aio_readdir>) pass the actual results and
294communicate failures by passing C<undef>.
290 295
291All functions expecting a filehandle keep a copy of the filehandle 296All functions expecting a filehandle keep a copy of the filehandle
292internally until the request has finished. 297internally until the request has finished.
293 298
294All functions return request objects of type L<IO::AIO::REQ> that allow 299All functions return request objects of type L<IO::AIO::REQ> that allow
295further manipulation of those requests while they are in-flight. 300further manipulation of those requests while they are in-flight.
296 301
297The pathnames you pass to these routines I<should> be absolute. The 302The pathnames you pass to these routines I<should> be absolute. The
298reason for this is that at the time the request is being executed, the 303reason for this is that at the time the request is being executed, the
299current working directory could have changed. Alternatively, you can make 304current working directory could have changed. Alternatively, you can
300sure that you never change the current working directory anywhere in 305make sure that you never change the current working directory anywhere
301the program and then use relative paths. Lastly, you can take advantage 306in the program and then use relative paths. You can also take advantage
302of IO::AIOs working directory abstraction - see the description of the 307of IO::AIOs working directory abstraction, that lets you specify paths
308relative to some previously-opened "working directory object" - see the
303C<IO::AIO::WD> class later in this document. 309description of the C<IO::AIO::WD> class later in this document.
304 310
305To encode pathnames as octets, either make sure you either: a) always pass 311To encode pathnames as octets, either make sure you either: a) always pass
306in filenames you got from outside (command line, readdir etc.) without 312in filenames you got from outside (command line, readdir etc.) without
307tinkering, b) are ASCII or ISO 8859-1, c) use the Encode module and encode 313tinkering, b) are in your native filesystem encoding, c) use the Encode
308your pathnames to the locale (or other) encoding in effect in the user 314module and encode your pathnames to the locale (or other) encoding in
309environment, d) use Glib::filename_from_unicode on unicode filenames or e) 315effect in the user environment, d) use Glib::filename_from_unicode on
310use something else to ensure your scalar has the correct contents. 316unicode filenames or e) use something else to ensure your scalar has the
317correct contents.
311 318
312This works, btw. independent of the internal UTF-8 bit, which IO::AIO 319This works, btw. independent of the internal UTF-8 bit, which IO::AIO
313handles correctly whether it is set or not. 320handles correctly whether it is set or not.
314 321
315=over 4 322=over 4
966 973
967 my $grp = aio_group $cb; 974 my $grp = aio_group $cb;
968 975
969 $maxreq = 4 if $maxreq <= 0; 976 $maxreq = 4 if $maxreq <= 0;
970 977
971 # stat once 978 # get a wd object
972 aioreq_pri $pri; 979 aioreq_pri $pri;
973 add $grp aio_stat $path, sub { 980 add $grp aio_wd $path, sub {
981 $_[0]
974 return $grp->result () if $_[0]; 982 or return $grp->result ();
975 my $now = time;
976 my $hash1 = join ":", (stat _)[0,1,3,7,9];
977 983
978 # read the directory entries 984 my $wd = [shift, "."];
985
986 # stat once
979 aioreq_pri $pri; 987 aioreq_pri $pri;
980 add $grp aio_readdirx $path, READDIR_DIRS_FIRST, sub { 988 add $grp aio_stat $wd, sub {
981 my $entries = shift
982 or return $grp->result (); 989 return $grp->result () if $_[0];
990 my $now = time;
991 my $hash1 = join ":", (stat _)[0,1,3,7,9];
983 992
984 # stat the dir another time 993 # read the directory entries
985 aioreq_pri $pri; 994 aioreq_pri $pri;
995 add $grp aio_readdirx $wd, READDIR_DIRS_FIRST, sub {
996 my $entries = shift
997 or return $grp->result ();
998
999 # stat the dir another time
1000 aioreq_pri $pri;
986 add $grp aio_stat $path, sub { 1001 add $grp aio_stat $wd, sub {
987 my $hash2 = join ":", (stat _)[0,1,3,7,9]; 1002 my $hash2 = join ":", (stat _)[0,1,3,7,9];
988 1003
989 my $ndirs; 1004 my $ndirs;
990 1005
991 # take the slow route if anything looks fishy 1006 # take the slow route if anything looks fishy
992 if ($hash1 ne $hash2 or (stat _)[9] == $now) { 1007 if ($hash1 ne $hash2 or (stat _)[9] == $now) {
993 $ndirs = -1; 1008 $ndirs = -1;
994 } else { 1009 } else {
995 # if nlink == 2, we are finished 1010 # if nlink == 2, we are finished
996 # for non-posix-fs's, we rely on nlink < 2 1011 # for non-posix-fs's, we rely on nlink < 2
997 $ndirs = (stat _)[3] - 2 1012 $ndirs = (stat _)[3] - 2
998 or return $grp->result ([], $entries); 1013 or return $grp->result ([], $entries);
999 } 1014 }
1000 1015
1001 my (@dirs, @nondirs); 1016 my (@dirs, @nondirs);
1002 1017
1003 my $statgrp = add $grp aio_group sub { 1018 my $statgrp = add $grp aio_group sub {
1004 $grp->result (\@dirs, \@nondirs); 1019 $grp->result (\@dirs, \@nondirs);
1005 }; 1020 };
1006 1021
1007 limit $statgrp $maxreq; 1022 limit $statgrp $maxreq;
1008 feed $statgrp sub { 1023 feed $statgrp sub {
1009 return unless @$entries; 1024 return unless @$entries;
1010 my $entry = shift @$entries; 1025 my $entry = shift @$entries;
1011 1026
1012 aioreq_pri $pri; 1027 aioreq_pri $pri;
1028 $wd->[1] = "$entry/.";
1013 add $statgrp aio_stat "$path/$entry/.", sub { 1029 add $statgrp aio_stat $wd, sub {
1014 if ($_[0] < 0) { 1030 if ($_[0] < 0) {
1015 push @nondirs, $entry; 1031 push @nondirs, $entry;
1016 } else { 1032 } else {
1017 # need to check for real directory 1033 # need to check for real directory
1018 aioreq_pri $pri; 1034 aioreq_pri $pri;
1035 $wd->[1] = $entry;
1019 add $statgrp aio_lstat "$path/$entry", sub { 1036 add $statgrp aio_lstat $wd, sub {
1020 if (-d _) { 1037 if (-d _) {
1021 push @dirs, $entry; 1038 push @dirs, $entry;
1022 1039
1023 unless (--$ndirs) { 1040 unless (--$ndirs) {
1024 push @nondirs, @$entries; 1041 push @nondirs, @$entries;
1025 feed $statgrp; 1042 feed $statgrp;
1043 }
1044 } else {
1045 push @nondirs, $entry;
1026 } 1046 }
1027 } else {
1028 push @nondirs, $entry;
1029 } 1047 }
1030 } 1048 }
1031 } 1049 };
1032 }; 1050 };
1033 }; 1051 };
1034 }; 1052 };
1035 }; 1053 };
1036 }; 1054 };
1287path, and on systems that allow it, also a directory file descriptor. 1305path, and on systems that allow it, also a directory file descriptor.
1288 1306
1289Everywhere where a pathname is accepted by IO::AIO (e.g. in C<aio_stat> 1307Everywhere where a pathname is accepted by IO::AIO (e.g. in C<aio_stat>
1290or C<aio_unlink>), one can specify an array reference with an IO::AIO::WD 1308or C<aio_unlink>), one can specify an array reference with an IO::AIO::WD
1291object and a pathname instead. If the pathname is absolute, the 1309object and a pathname instead. If the pathname is absolute, the
1292IO::AIO::WD objetc is ignored, otherwise the pathname is resolved relative 1310IO::AIO::WD object is ignored, otherwise the pathname is resolved relative
1293to that IO::AIO::WD object. 1311to that IO::AIO::WD object.
1294 1312
1295For example, to get a wd object for F</etc> and then stat F<passwd> 1313For example, to get a wd object for F</etc> and then stat F<passwd>
1296inside, you would write: 1314inside, you would write:
1297 1315
1496 1514
1497Sets a feeder/generator on this group: every group can have an attached 1515Sets a feeder/generator on this group: every group can have an attached
1498generator that generates requests if idle. The idea behind this is that, 1516generator that generates requests if idle. The idea behind this is that,
1499although you could just queue as many requests as you want in a group, 1517although you could just queue as many requests as you want in a group,
1500this might starve other requests for a potentially long time. For example, 1518this might starve other requests for a potentially long time. For example,
1501C<aio_scandir> might generate hundreds of thousands C<aio_stat> requests, 1519C<aio_scandir> might generate hundreds of thousands of C<aio_stat>
1502delaying any later requests for a long time. 1520requests, delaying any later requests for a long time.
1503 1521
1504To avoid this, and allow incremental generation of requests, you can 1522To avoid this, and allow incremental generation of requests, you can
1505instead a group and set a feeder on it that generates those requests. The 1523instead a group and set a feeder on it that generates those requests. The
1506feed callback will be called whenever there are few enough (see C<limit>, 1524feed callback will be called whenever there are few enough (see C<limit>,
1507below) requests active in the group itself and is expected to queue more 1525below) requests active in the group itself and is expected to queue more

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines