--- IO-AIO/AIO.pm 2008/04/26 12:00:23 1.122 +++ IO-AIO/AIO.pm 2008/05/10 19:25:33 1.124 @@ -196,7 +196,7 @@ use base 'Exporter'; BEGIN { - our $VERSION = '2.62'; + our $VERSION = '3.0'; our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat aio_lstat aio_unlink aio_rmdir aio_readdir @@ -206,7 +206,7 @@ aio_nop aio_mknod aio_load aio_rmtree aio_mkdir aio_chown aio_chmod aio_utime aio_truncate); - our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice aio_block)); + 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 nreqs nready npending nthreads @@ -542,26 +542,24 @@ =cut sub aio_load($$;$) { - aio_block { - my ($path, undef, $cb) = @_; - my $data = \$_[1]; + my ($path, undef, $cb) = @_; + my $data = \$_[1]; - my $pri = aioreq_pri; - my $grp = aio_group $cb; + my $pri = aioreq_pri; + my $grp = aio_group $cb; - aioreq_pri $pri; - add $grp aio_open $path, O_RDONLY, 0, sub { - my $fh = shift - or return $grp->result (-1); + aioreq_pri $pri; + add $grp aio_open $path, O_RDONLY, 0, sub { + my $fh = shift + or return $grp->result (-1); - aioreq_pri $pri; - add $grp aio_read $fh, 0, (-s $fh), $$data, 0, sub { - $grp->result ($_[0]); - }; + aioreq_pri $pri; + add $grp aio_read $fh, 0, (-s $fh), $$data, 0, sub { + $grp->result ($_[0]); }; + }; - $grp - } + $grp } =item aio_copy $srcpath, $dstpath, $callback->($status) @@ -582,54 +580,52 @@ =cut sub aio_copy($$;$) { - aio_block { - my ($src, $dst, $cb) = @_; + my ($src, $dst, $cb) = @_; - my $pri = aioreq_pri; - my $grp = aio_group $cb; + my $pri = aioreq_pri; + my $grp = aio_group $cb; - aioreq_pri $pri; - add $grp aio_open $src, O_RDONLY, 0, sub { - if (my $src_fh = $_[0]) { - my @stat = stat $src_fh; + aioreq_pri $pri; + add $grp aio_open $src, O_RDONLY, 0, sub { + if (my $src_fh = $_[0]) { + my @stat = stat $src_fh; - aioreq_pri $pri; - add $grp aio_open $dst, O_CREAT | O_WRONLY | O_TRUNC, 0200, sub { - if (my $dst_fh = $_[0]) { - aioreq_pri $pri; - add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub { - if ($_[0] == $stat[7]) { - $grp->result (0); - close $src_fh; - - # those should not normally block. should. should. - utime $stat[8], $stat[9], $dst; - chmod $stat[2] & 07777, $dst_fh; - chown $stat[4], $stat[5], $dst_fh; - - aioreq_pri $pri; - add $grp aio_close $dst_fh; - } else { - $grp->result (-1); - close $src_fh; - close $dst_fh; + aioreq_pri $pri; + add $grp aio_open $dst, O_CREAT | O_WRONLY | O_TRUNC, 0200, sub { + if (my $dst_fh = $_[0]) { + aioreq_pri $pri; + add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub { + if ($_[0] == $stat[7]) { + $grp->result (0); + close $src_fh; + + # those should not normally block. should. should. + utime $stat[8], $stat[9], $dst; + chmod $stat[2] & 07777, $dst_fh; + chown $stat[4], $stat[5], $dst_fh; + + aioreq_pri $pri; + add $grp aio_close $dst_fh; + } else { + $grp->result (-1); + close $src_fh; + close $dst_fh; + + aioreq $pri; + add $grp aio_unlink $dst; + } + }; + } else { + $grp->result (-1); + } + }, - aioreq $pri; - add $grp aio_unlink $dst; - } - }; - } else { - $grp->result (-1); - } - }, - - } else { - $grp->result (-1); - } - }; + } else { + $grp->result (-1); + } + }; - $grp - } + $grp } =item aio_move $srcpath, $dstpath, $callback->($status) @@ -645,31 +641,29 @@ =cut sub aio_move($$;$) { - aio_block { - my ($src, $dst, $cb) = @_; + my ($src, $dst, $cb) = @_; - my $pri = aioreq_pri; - my $grp = aio_group $cb; + my $pri = aioreq_pri; + my $grp = aio_group $cb; - aioreq_pri $pri; - add $grp aio_rename $src, $dst, sub { - if ($_[0] && $! == EXDEV) { - aioreq_pri $pri; - add $grp aio_copy $src, $dst, sub { - $grp->result ($_[0]); - - if (!$_[0]) { - aioreq_pri $pri; - add $grp aio_unlink $src; - } - }; - } else { + aioreq_pri $pri; + add $grp aio_rename $src, $dst, sub { + if ($_[0] && $! == EXDEV) { + aioreq_pri $pri; + add $grp aio_copy $src, $dst, sub { $grp->result ($_[0]); - } - }; - $grp - } + if (!$_[0]) { + aioreq_pri $pri; + add $grp aio_unlink $src; + } + }; + } else { + $grp->result ($_[0]); + } + }; + + $grp } =item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs) @@ -727,91 +721,89 @@ =cut sub aio_scandir($$;$) { - aio_block { - my ($path, $maxreq, $cb) = @_; + my ($path, $maxreq, $cb) = @_; + + my $pri = aioreq_pri; - my $pri = aioreq_pri; + my $grp = aio_group $cb; - my $grp = aio_group $cb; + $maxreq = 4 if $maxreq <= 0; - $maxreq = 4 if $maxreq <= 0; + # stat once + aioreq_pri $pri; + add $grp aio_stat $path, sub { + return $grp->result () if $_[0]; + my $now = time; + my $hash1 = join ":", (stat _)[0,1,3,7,9]; - # stat once + # read the directory entries aioreq_pri $pri; - add $grp aio_stat $path, sub { - return $grp->result () if $_[0]; - my $now = time; - my $hash1 = join ":", (stat _)[0,1,3,7,9]; + add $grp aio_readdir $path, sub { + my $entries = shift + or return $grp->result (); - # read the directory entries + # stat the dir another time aioreq_pri $pri; - add $grp aio_readdir $path, sub { - my $entries = shift - or return $grp->result (); + add $grp aio_stat $path, sub { + my $hash2 = join ":", (stat _)[0,1,3,7,9]; - # stat the dir another time - aioreq_pri $pri; - add $grp aio_stat $path, sub { - my $hash2 = join ":", (stat _)[0,1,3,7,9]; + my $ndirs; - my $ndirs; + # take the slow route if anything looks fishy + if ($hash1 ne $hash2 or (stat _)[9] == $now) { + $ndirs = -1; + } else { + # if nlink == 2, we are finished + # on non-posix-fs's, we rely on nlink < 2 + $ndirs = (stat _)[3] - 2 + or return $grp->result ([], $entries); + } + + # sort into likely dirs and likely nondirs + # dirs == files without ".", short entries first + $entries = [map $_->[0], + sort { $b->[1] cmp $a->[1] } + map [$_, sprintf "%s%04d", (/.\./ ? "1" : "0"), length], + @$entries]; - # take the slow route if anything looks fishy - if ($hash1 ne $hash2 or (stat _)[9] == $now) { - $ndirs = -1; - } else { - # if nlink == 2, we are finished - # on non-posix-fs's, we rely on nlink < 2 - $ndirs = (stat _)[3] - 2 - or return $grp->result ([], $entries); - } - - # sort into likely dirs and likely nondirs - # dirs == files without ".", short entries first - $entries = [map $_->[0], - sort { $b->[1] cmp $a->[1] } - map [$_, sprintf "%s%04d", (/.\./ ? "1" : "0"), length], - @$entries]; + my (@dirs, @nondirs); - my (@dirs, @nondirs); + my $statgrp = add $grp aio_group sub { + $grp->result (\@dirs, \@nondirs); + }; - my $statgrp = add $grp aio_group sub { - $grp->result (\@dirs, \@nondirs); - }; + limit $statgrp $maxreq; + feed $statgrp sub { + return unless @$entries; + my $entry = pop @$entries; - limit $statgrp $maxreq; - feed $statgrp sub { - return unless @$entries; - my $entry = pop @$entries; - - aioreq_pri $pri; - add $statgrp aio_stat "$path/$entry/.", sub { - if ($_[0] < 0) { - push @nondirs, $entry; - } else { - # need to check for real directory - aioreq_pri $pri; - add $statgrp aio_lstat "$path/$entry", sub { - if (-d _) { - push @dirs, $entry; - - unless (--$ndirs) { - push @nondirs, @$entries; - feed $statgrp; - } - } else { - push @nondirs, $entry; + aioreq_pri $pri; + add $statgrp aio_stat "$path/$entry/.", sub { + if ($_[0] < 0) { + push @nondirs, $entry; + } else { + # need to check for real directory + aioreq_pri $pri; + add $statgrp aio_lstat "$path/$entry", sub { + if (-d _) { + push @dirs, $entry; + + unless (--$ndirs) { + push @nondirs, @$entries; + feed $statgrp; } + } else { + push @nondirs, $entry; } } - }; + } }; }; }; }; + }; - $grp - } + $grp } =item aio_rmtree $path, $callback->($status) @@ -825,30 +817,28 @@ sub aio_rmtree; sub aio_rmtree($;$) { - aio_block { - my ($path, $cb) = @_; + my ($path, $cb) = @_; - my $pri = aioreq_pri; - my $grp = aio_group $cb; + my $pri = aioreq_pri; + my $grp = aio_group $cb; - aioreq_pri $pri; - add $grp aio_scandir $path, 0, sub { - my ($dirs, $nondirs) = @_; + aioreq_pri $pri; + add $grp aio_scandir $path, 0, sub { + my ($dirs, $nondirs) = @_; - my $dirgrp = aio_group sub { - add $grp aio_rmdir $path, sub { - $grp->result ($_[0]); - }; + my $dirgrp = aio_group sub { + add $grp aio_rmdir $path, sub { + $grp->result ($_[0]); }; + }; - (aioreq_pri $pri), add $dirgrp aio_rmtree "$path/$_" for @$dirs; - (aioreq_pri $pri), add $dirgrp aio_unlink "$path/$_" for @$nondirs; + (aioreq_pri $pri), add $dirgrp aio_rmtree "$path/$_" for @$dirs; + (aioreq_pri $pri), add $dirgrp aio_unlink "$path/$_" for @$nondirs; - add $grp $dirgrp; - }; + add $grp $dirgrp; + }; - $grp - } + $grp } =item aio_sync $callback->($status) @@ -882,30 +872,28 @@ =cut sub aio_pathsync($;$) { - aio_block { - my ($path, $cb) = @_; + my ($path, $cb) = @_; - my $pri = aioreq_pri; - my $grp = aio_group $cb; + my $pri = aioreq_pri; + my $grp = aio_group $cb; - aioreq_pri $pri; - add $grp aio_open $path, O_RDONLY, 0, sub { - my ($fh) = @_; - if ($fh) { - aioreq_pri $pri; - add $grp aio_fsync $fh, sub { - $grp->result ($_[0]); + aioreq_pri $pri; + add $grp aio_open $path, O_RDONLY, 0, sub { + my ($fh) = @_; + if ($fh) { + aioreq_pri $pri; + add $grp aio_fsync $fh, sub { + $grp->result ($_[0]); - aioreq_pri $pri; - add $grp aio_close $fh; - }; - } else { - $grp->result (-1); - } - }; + aioreq_pri $pri; + add $grp aio_close $fh; + }; + } else { + $grp->result (-1); + } + }; - $grp - } + $grp } =item aio_group $callback->(...) @@ -1261,7 +1249,7 @@ 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 +=item IO::AIO::max_outstanding $maxreqs This is a very bad function to use in interactive programs because it blocks, and a bad way to reduce concurrency because it is inexact: Better @@ -1276,7 +1264,7 @@ number of outstanding requests. You can still queue as many requests as you want. Therefore, -C is mainly useful in simple scripts (with low values) or +C is mainly useful in simple scripts (with low values) or as a stop gap to shield against fatal memory overflow (with large values). =back