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.94 by root, Wed Nov 8 02:01:02 2006 UTC vs.
Revision 1.95 by root, Sun Nov 26 18:28:37 2006 UTC

196 196
197 our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat 197 our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat
198 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink 198 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink
199 aio_readlink aio_fsync aio_fdatasync aio_readahead aio_rename aio_link 199 aio_readlink aio_fsync aio_fdatasync aio_readahead aio_rename aio_link
200 aio_move aio_copy aio_group aio_nop aio_mknod); 200 aio_move aio_copy aio_group aio_nop aio_mknod);
201 our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice)); 201 our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice aio_block));
202 our @EXPORT_OK = qw(poll_fileno poll_cb poll_wait flush 202 our @EXPORT_OK = qw(poll_fileno poll_cb poll_wait flush
203 min_parallel max_parallel max_idle 203 min_parallel max_parallel max_idle
204 nreqs nready npending nthreads 204 nreqs nready npending nthreads
205 max_poll_time max_poll_reqs); 205 max_poll_time max_poll_reqs);
206 206
462errors are being ignored. 462errors are being ignored.
463 463
464=cut 464=cut
465 465
466sub aio_copy($$;$) { 466sub aio_copy($$;$) {
467 aio_block {
467 my ($src, $dst, $cb) = @_; 468 my ($src, $dst, $cb) = @_;
468 469
469 my $pri = aioreq_pri; 470 my $pri = aioreq_pri;
470 my $grp = aio_group $cb; 471 my $grp = aio_group $cb;
471 472
472 aioreq_pri $pri; 473 aioreq_pri $pri;
473 add $grp aio_open $src, O_RDONLY, 0, sub { 474 add $grp aio_open $src, O_RDONLY, 0, sub {
474 if (my $src_fh = $_[0]) { 475 if (my $src_fh = $_[0]) {
475 my @stat = stat $src_fh; 476 my @stat = stat $src_fh;
476 477
477 aioreq_pri $pri; 478 aioreq_pri $pri;
478 add $grp aio_open $dst, O_CREAT | O_WRONLY | O_TRUNC, 0200, sub { 479 add $grp aio_open $dst, O_CREAT | O_WRONLY | O_TRUNC, 0200, sub {
479 if (my $dst_fh = $_[0]) { 480 if (my $dst_fh = $_[0]) {
480 aioreq_pri $pri; 481 aioreq_pri $pri;
481 add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub { 482 add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub {
482 if ($_[0] == $stat[7]) { 483 if ($_[0] == $stat[7]) {
483 $grp->result (0); 484 $grp->result (0);
484 close $src_fh; 485 close $src_fh;
485 486
486 # those should not normally block. should. should. 487 # those should not normally block. should. should.
487 utime $stat[8], $stat[9], $dst; 488 utime $stat[8], $stat[9], $dst;
488 chmod $stat[2] & 07777, $dst_fh; 489 chmod $stat[2] & 07777, $dst_fh;
489 chown $stat[4], $stat[5], $dst_fh; 490 chown $stat[4], $stat[5], $dst_fh;
490 close $dst_fh; 491 close $dst_fh;
491 } else { 492 } else {
492 $grp->result (-1); 493 $grp->result (-1);
493 close $src_fh; 494 close $src_fh;
494 close $dst_fh; 495 close $dst_fh;
495 496
496 aioreq $pri; 497 aioreq $pri;
497 add $grp aio_unlink $dst; 498 add $grp aio_unlink $dst;
499 }
498 } 500 };
501 } else {
502 $grp->result (-1);
499 }; 503 }
500 } else {
501 $grp->result (-1);
502 } 504 },
505
506 } else {
507 $grp->result (-1);
503 }, 508 }
504
505 } else {
506 $grp->result (-1);
507 } 509 };
510
511 $grp
508 }; 512 }
509
510 $grp
511} 513}
512 514
513=item aio_move $srcpath, $dstpath, $callback->($status) 515=item aio_move $srcpath, $dstpath, $callback->($status)
514 516
515Try to move the I<file> (directories not supported as either source or 517Try to move the I<file> (directories not supported as either source or
521that is successful, unlinking the C<$srcpath>. 523that is successful, unlinking the C<$srcpath>.
522 524
523=cut 525=cut
524 526
525sub aio_move($$;$) { 527sub aio_move($$;$) {
528 aio_block {
526 my ($src, $dst, $cb) = @_; 529 my ($src, $dst, $cb) = @_;
527 530
528 my $pri = aioreq_pri; 531 my $pri = aioreq_pri;
529 my $grp = aio_group $cb; 532 my $grp = aio_group $cb;
530 533
531 aioreq_pri $pri; 534 aioreq_pri $pri;
532 add $grp aio_rename $src, $dst, sub { 535 add $grp aio_rename $src, $dst, sub {
533 if ($_[0] && $! == EXDEV) { 536 if ($_[0] && $! == EXDEV) {
534 aioreq_pri $pri; 537 aioreq_pri $pri;
535 add $grp aio_copy $src, $dst, sub { 538 add $grp aio_copy $src, $dst, sub {
539 $grp->result ($_[0]);
540
541 if (!$_[0]) {
542 aioreq_pri $pri;
543 add $grp aio_unlink $src;
544 }
545 };
546 } else {
536 $grp->result ($_[0]); 547 $grp->result ($_[0]);
537
538 if (!$_[0]) {
539 aioreq_pri $pri;
540 add $grp aio_unlink $src;
541 }
542 }; 548 }
543 } else {
544 $grp->result ($_[0]);
545 } 549 };
550
551 $grp
546 }; 552 }
547
548 $grp
549} 553}
550 554
551=item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs) 555=item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs)
552 556
553Scans a directory (similar to C<aio_readdir>) but additionally tries to 557Scans a directory (similar to C<aio_readdir>) but additionally tries to
601directory counting heuristic. 605directory counting heuristic.
602 606
603=cut 607=cut
604 608
605sub aio_scandir($$$) { 609sub aio_scandir($$$) {
610 aio_block {
606 my ($path, $maxreq, $cb) = @_; 611 my ($path, $maxreq, $cb) = @_;
607 612
608 my $pri = aioreq_pri; 613 my $pri = aioreq_pri;
609 614
610 my $grp = aio_group $cb; 615 my $grp = aio_group $cb;
611 616
612 $maxreq = 4 if $maxreq <= 0; 617 $maxreq = 4 if $maxreq <= 0;
613 618
614 # stat once 619 # stat once
615 aioreq_pri $pri;
616 add $grp aio_stat $path, sub {
617 return $grp->result () if $_[0];
618 my $now = time;
619 my $hash1 = join ":", (stat _)[0,1,3,7,9];
620
621 # read the directory entries
622 aioreq_pri $pri; 620 aioreq_pri $pri;
623 add $grp aio_readdir $path, sub { 621 add $grp aio_stat $path, sub {
624 my $entries = shift
625 or return $grp->result (); 622 return $grp->result () if $_[0];
623 my $now = time;
624 my $hash1 = join ":", (stat _)[0,1,3,7,9];
626 625
627 # stat the dir another time 626 # read the directory entries
628 aioreq_pri $pri; 627 aioreq_pri $pri;
628 add $grp aio_readdir $path, sub {
629 my $entries = shift
630 or return $grp->result ();
631
632 # stat the dir another time
633 aioreq_pri $pri;
629 add $grp aio_stat $path, sub { 634 add $grp aio_stat $path, sub {
630 my $hash2 = join ":", (stat _)[0,1,3,7,9]; 635 my $hash2 = join ":", (stat _)[0,1,3,7,9];
631 636
632 my $ndirs; 637 my $ndirs;
633 638
634 # take the slow route if anything looks fishy 639 # take the slow route if anything looks fishy
635 if ($hash1 ne $hash2 or (stat _)[9] == $now) { 640 if ($hash1 ne $hash2 or (stat _)[9] == $now) {
636 $ndirs = -1; 641 $ndirs = -1;
637 } else { 642 } else {
638 # if nlink == 2, we are finished 643 # if nlink == 2, we are finished
639 # on non-posix-fs's, we rely on nlink < 2 644 # on non-posix-fs's, we rely on nlink < 2
640 $ndirs = (stat _)[3] - 2 645 $ndirs = (stat _)[3] - 2
641 or return $grp->result ([], $entries); 646 or return $grp->result ([], $entries);
642 } 647 }
643 648
644 # sort into likely dirs and likely nondirs 649 # sort into likely dirs and likely nondirs
645 # dirs == files without ".", short entries first 650 # dirs == files without ".", short entries first
646 $entries = [map $_->[0], 651 $entries = [map $_->[0],
647 sort { $b->[1] cmp $a->[1] } 652 sort { $b->[1] cmp $a->[1] }
648 map [$_, sprintf "%s%04d", (/.\./ ? "1" : "0"), length], 653 map [$_, sprintf "%s%04d", (/.\./ ? "1" : "0"), length],
649 @$entries]; 654 @$entries];
650 655
651 my (@dirs, @nondirs); 656 my (@dirs, @nondirs);
652 657
653 my $statgrp = add $grp aio_group sub { 658 my $statgrp = add $grp aio_group sub {
654 $grp->result (\@dirs, \@nondirs); 659 $grp->result (\@dirs, \@nondirs);
655 }; 660 };
656 661
657 limit $statgrp $maxreq; 662 limit $statgrp $maxreq;
658 feed $statgrp sub { 663 feed $statgrp sub {
659 return unless @$entries; 664 return unless @$entries;
660 my $entry = pop @$entries; 665 my $entry = pop @$entries;
661 666
662 aioreq_pri $pri; 667 aioreq_pri $pri;
663 add $statgrp aio_stat "$path/$entry/.", sub { 668 add $statgrp aio_stat "$path/$entry/.", sub {
664 if ($_[0] < 0) { 669 if ($_[0] < 0) {
665 push @nondirs, $entry; 670 push @nondirs, $entry;
666 } else { 671 } else {
667 # need to check for real directory 672 # need to check for real directory
668 aioreq_pri $pri; 673 aioreq_pri $pri;
669 add $statgrp aio_lstat "$path/$entry", sub { 674 add $statgrp aio_lstat "$path/$entry", sub {
670 if (-d _) { 675 if (-d _) {
671 push @dirs, $entry; 676 push @dirs, $entry;
672 677
673 unless (--$ndirs) { 678 unless (--$ndirs) {
674 push @nondirs, @$entries; 679 push @nondirs, @$entries;
675 feed $statgrp; 680 feed $statgrp;
681 }
682 } else {
683 push @nondirs, $entry;
676 } 684 }
677 } else {
678 push @nondirs, $entry;
679 } 685 }
680 } 686 }
681 } 687 };
682 }; 688 };
683 }; 689 };
684 }; 690 };
685 }; 691 };
692
693 $grp
686 }; 694 }
687
688 $grp
689} 695}
690 696
691=item aio_fsync $fh, $callback->($status) 697=item aio_fsync $fh, $callback->($status)
692 698
693Asynchronously call fsync on the given filehandle and call the callback 699Asynchronously call fsync on the given filehandle and call the callback
1110 *$sym 1116 *$sym
1111} 1117}
1112 1118
1113min_parallel 8; 1119min_parallel 8;
1114 1120
1115END { 1121END { flush }
1116 min_parallel 1;
1117 flush;
1118};
1119 1122
11201; 11231;
1121 1124
1122=head2 FORK BEHAVIOUR 1125=head2 FORK BEHAVIOUR
1123 1126

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines