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.115 by root, Mon Sep 24 18:14:00 2007 UTC vs.
Revision 1.131 by root, Tue Jul 15 10:42:26 2008 UTC

26 $req->cancel; # cancel request if still in queue 26 $req->cancel; # cancel request if still in queue
27 27
28 my $grp = aio_group sub { print "all stats done\n" }; 28 my $grp = aio_group sub { print "all stats done\n" };
29 add $grp aio_stat "..." for ...; 29 add $grp aio_stat "..." for ...;
30 30
31 # AnyEvent integration (EV, Event, Glib, Tk, POE, urxvt, pureperl...)
32 use AnyEvent::AIO;
33
31 # AnyEvent integration 34 # EV integration
32 open my $fh, "<&=" . IO::AIO::poll_fileno or die "$!"; 35 my $w = EV::io IO::AIO::poll_fileno, EV::READ, \&IO::AIO::poll_cb;
33 my $w = AnyEvent->io (fh => $fh, poll => 'r', cb => sub { IO::AIO::poll_cb });
34 36
35 # Event integration 37 # Event integration
36 Event->io (fd => IO::AIO::poll_fileno, 38 Event->io (fd => IO::AIO::poll_fileno,
37 poll => 'r', 39 poll => 'r',
38 cb => \&IO::AIO::poll_cb); 40 cb => \&IO::AIO::poll_cb);
183 185
184=cut 186=cut
185 187
186package IO::AIO; 188package IO::AIO;
187 189
190use Carp ();
191
188no warnings; 192no warnings;
189use strict 'vars'; 193use strict 'vars';
190 194
191use base 'Exporter'; 195use base 'Exporter';
192 196
193BEGIN { 197BEGIN {
194 our $VERSION = '2.41'; 198 our $VERSION = '3.06';
195 199
196 our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat 200 our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close
197 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink 201 aio_stat aio_lstat aio_unlink aio_rmdir aio_readdir
198 aio_readlink aio_fsync aio_fdatasync aio_readahead aio_rename aio_link 202 aio_scandir aio_symlink aio_readlink aio_sync aio_fsync
203 aio_fdatasync aio_pathsync aio_readahead
204 aio_rename aio_link aio_move aio_copy aio_group
199 aio_move aio_copy aio_group aio_nop aio_mknod aio_load aio_rmtree aio_mkdir 205 aio_nop aio_mknod aio_load aio_rmtree aio_mkdir aio_chown
200 aio_chown aio_chmod aio_utime aio_truncate); 206 aio_chmod aio_utime aio_truncate);
207
201 our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice aio_block)); 208 our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice));
202 our @EXPORT_OK = qw(poll_fileno poll_cb poll_wait flush 209 our @EXPORT_OK = qw(poll_fileno poll_cb poll_wait flush
203 min_parallel max_parallel max_idle 210 min_parallel max_parallel max_idle
204 nreqs nready npending nthreads 211 nreqs nready npending nthreads
205 max_poll_time max_poll_reqs); 212 max_poll_time max_poll_reqs);
206 213
311 318
312 319
313=item aio_close $fh, $callback->($status) 320=item aio_close $fh, $callback->($status)
314 321
315Asynchronously close a file and call the callback with the result 322Asynchronously close a file and call the callback with the result
316code. I<WARNING:> although accepted, you should not pass in a perl 323code.
317filehandle here, as perl will likely close the file descriptor another
318time when the filehandle is destroyed. Normally, you can safely call perls
319C<close> or just let filehandles go out of scope.
320 324
321This is supposed to be a bug in the API, so that might change. It's 325Unfortunately, you can't do this to perl. Perl I<insists> very strongly on
322therefore best to avoid this function. 326closing the file descriptor associated with the filehandle itself.
323 327
328Therefore, C<aio_close> will not close the filehandle - instead it will
329use dup2 to overwrite the file descriptor with the write-end of a pipe
330(the pipe fd will be created on demand and will be cached).
331
332Or in other words: the file descriptor will be closed, but it will not be
333free for reuse until the perl filehandle is closed.
334
335=cut
324 336
325=item aio_read $fh,$offset,$length, $data,$dataoffset, $callback->($retval) 337=item aio_read $fh,$offset,$length, $data,$dataoffset, $callback->($retval)
326 338
327=item aio_write $fh,$offset,$length, $data,$dataoffset, $callback->($retval) 339=item aio_write $fh,$offset,$length, $data,$dataoffset, $callback->($retval)
328 340
527memory. Status is the same as with aio_read. 539memory. Status is the same as with aio_read.
528 540
529=cut 541=cut
530 542
531sub aio_load($$;$) { 543sub aio_load($$;$) {
532 aio_block {
533 my ($path, undef, $cb) = @_; 544 my ($path, undef, $cb) = @_;
534 my $data = \$_[1]; 545 my $data = \$_[1];
535 546
536 my $pri = aioreq_pri; 547 my $pri = aioreq_pri;
537 my $grp = aio_group $cb; 548 my $grp = aio_group $cb;
549
550 aioreq_pri $pri;
551 add $grp aio_open $path, O_RDONLY, 0, sub {
552 my $fh = shift
553 or return $grp->result (-1);
538 554
539 aioreq_pri $pri; 555 aioreq_pri $pri;
540 add $grp aio_open $path, O_RDONLY, 0, sub {
541 my $fh = shift
542 or return $grp->result (-1);
543
544 aioreq_pri $pri;
545 add $grp aio_read $fh, 0, (-s $fh), $$data, 0, sub { 556 add $grp aio_read $fh, 0, (-s $fh), $$data, 0, sub {
546 $grp->result ($_[0]); 557 $grp->result ($_[0]);
547 };
548 }; 558 };
549
550 $grp
551 } 559 };
560
561 $grp
552} 562}
553 563
554=item aio_copy $srcpath, $dstpath, $callback->($status) 564=item aio_copy $srcpath, $dstpath, $callback->($status)
555 565
556Try to copy the I<file> (directories not supported as either source or 566Try to copy the I<file> (directories not supported as either source or
567errors are being ignored. 577errors are being ignored.
568 578
569=cut 579=cut
570 580
571sub aio_copy($$;$) { 581sub aio_copy($$;$) {
572 aio_block {
573 my ($src, $dst, $cb) = @_; 582 my ($src, $dst, $cb) = @_;
574 583
575 my $pri = aioreq_pri; 584 my $pri = aioreq_pri;
576 my $grp = aio_group $cb; 585 my $grp = aio_group $cb;
577 586
578 aioreq_pri $pri; 587 aioreq_pri $pri;
579 add $grp aio_open $src, O_RDONLY, 0, sub { 588 add $grp aio_open $src, O_RDONLY, 0, sub {
580 if (my $src_fh = $_[0]) { 589 if (my $src_fh = $_[0]) {
581 my @stat = stat $src_fh; 590 my @stat = stat $src_fh;
582 591
583 aioreq_pri $pri; 592 aioreq_pri $pri;
584 add $grp aio_open $dst, O_CREAT | O_WRONLY | O_TRUNC, 0200, sub { 593 add $grp aio_open $dst, O_CREAT | O_WRONLY | O_TRUNC, 0200, sub {
585 if (my $dst_fh = $_[0]) { 594 if (my $dst_fh = $_[0]) {
586 aioreq_pri $pri; 595 aioreq_pri $pri;
587 add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub { 596 add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub {
588 if ($_[0] == $stat[7]) { 597 if ($_[0] == $stat[7]) {
589 $grp->result (0); 598 $grp->result (0);
590 close $src_fh; 599 close $src_fh;
591 600
592 # those should not normally block. should. should. 601 # those should not normally block. should. should.
593 utime $stat[8], $stat[9], $dst; 602 utime $stat[8], $stat[9], $dst;
594 chmod $stat[2] & 07777, $dst_fh; 603 chmod $stat[2] & 07777, $dst_fh;
595 chown $stat[4], $stat[5], $dst_fh; 604 chown $stat[4], $stat[5], $dst_fh;
605
606 aioreq_pri $pri;
596 close $dst_fh; 607 add $grp aio_close $dst_fh;
597 } else { 608 } else {
598 $grp->result (-1); 609 $grp->result (-1);
599 close $src_fh; 610 close $src_fh;
600 close $dst_fh; 611 close $dst_fh;
601 612
602 aioreq $pri; 613 aioreq $pri;
603 add $grp aio_unlink $dst; 614 add $grp aio_unlink $dst;
604 }
605 }; 615 }
606 } else {
607 $grp->result (-1);
608 } 616 };
617 } else {
618 $grp->result (-1);
609 }, 619 }
610
611 } else {
612 $grp->result (-1);
613 } 620 },
621
622 } else {
623 $grp->result (-1);
614 }; 624 }
615
616 $grp
617 } 625 };
626
627 $grp
618} 628}
619 629
620=item aio_move $srcpath, $dstpath, $callback->($status) 630=item aio_move $srcpath, $dstpath, $callback->($status)
621 631
622Try to move the I<file> (directories not supported as either source or 632Try to move the I<file> (directories not supported as either source or
628that is successful, unlinking the C<$srcpath>. 638that is successful, unlinking the C<$srcpath>.
629 639
630=cut 640=cut
631 641
632sub aio_move($$;$) { 642sub aio_move($$;$) {
633 aio_block {
634 my ($src, $dst, $cb) = @_; 643 my ($src, $dst, $cb) = @_;
635 644
636 my $pri = aioreq_pri; 645 my $pri = aioreq_pri;
637 my $grp = aio_group $cb; 646 my $grp = aio_group $cb;
638 647
639 aioreq_pri $pri; 648 aioreq_pri $pri;
640 add $grp aio_rename $src, $dst, sub { 649 add $grp aio_rename $src, $dst, sub {
641 if ($_[0] && $! == EXDEV) { 650 if ($_[0] && $! == EXDEV) {
642 aioreq_pri $pri; 651 aioreq_pri $pri;
643 add $grp aio_copy $src, $dst, sub { 652 add $grp aio_copy $src, $dst, sub {
644 $grp->result ($_[0]);
645
646 if (!$_[0]) {
647 aioreq_pri $pri;
648 add $grp aio_unlink $src;
649 }
650 };
651 } else {
652 $grp->result ($_[0]); 653 $grp->result ($_[0]);
654
655 if (!$_[0]) {
656 aioreq_pri $pri;
657 add $grp aio_unlink $src;
658 }
653 } 659 };
660 } else {
661 $grp->result ($_[0]);
654 }; 662 }
655
656 $grp
657 } 663 };
664
665 $grp
658} 666}
659 667
660=item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs) 668=item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs)
661 669
662Scans a directory (similar to C<aio_readdir>) but additionally tries to 670Scans a directory (similar to C<aio_readdir>) but additionally tries to
710directory counting heuristic. 718directory counting heuristic.
711 719
712=cut 720=cut
713 721
714sub aio_scandir($$;$) { 722sub aio_scandir($$;$) {
715 aio_block {
716 my ($path, $maxreq, $cb) = @_; 723 my ($path, $maxreq, $cb) = @_;
717 724
718 my $pri = aioreq_pri; 725 my $pri = aioreq_pri;
719 726
720 my $grp = aio_group $cb; 727 my $grp = aio_group $cb;
721 728
722 $maxreq = 4 if $maxreq <= 0; 729 $maxreq = 4 if $maxreq <= 0;
723 730
724 # stat once 731 # stat once
732 aioreq_pri $pri;
733 add $grp aio_stat $path, sub {
734 return $grp->result () if $_[0];
735 my $now = time;
736 my $hash1 = join ":", (stat _)[0,1,3,7,9];
737
738 # read the directory entries
725 aioreq_pri $pri; 739 aioreq_pri $pri;
726 add $grp aio_stat $path, sub { 740 add $grp aio_readdir $path, sub {
741 my $entries = shift
727 return $grp->result () if $_[0]; 742 or return $grp->result ();
728 my $now = time;
729 my $hash1 = join ":", (stat _)[0,1,3,7,9];
730 743
731 # read the directory entries 744 # stat the dir another time
732 aioreq_pri $pri; 745 aioreq_pri $pri;
733 add $grp aio_readdir $path, sub {
734 my $entries = shift
735 or return $grp->result ();
736
737 # stat the dir another time
738 aioreq_pri $pri;
739 add $grp aio_stat $path, sub { 746 add $grp aio_stat $path, sub {
740 my $hash2 = join ":", (stat _)[0,1,3,7,9]; 747 my $hash2 = join ":", (stat _)[0,1,3,7,9];
741 748
742 my $ndirs; 749 my $ndirs;
743 750
744 # take the slow route if anything looks fishy 751 # take the slow route if anything looks fishy
745 if ($hash1 ne $hash2 or (stat _)[9] == $now) { 752 if ($hash1 ne $hash2 or (stat _)[9] == $now) {
746 $ndirs = -1; 753 $ndirs = -1;
747 } else { 754 } else {
748 # if nlink == 2, we are finished 755 # if nlink == 2, we are finished
749 # on non-posix-fs's, we rely on nlink < 2 756 # on non-posix-fs's, we rely on nlink < 2
750 $ndirs = (stat _)[3] - 2 757 $ndirs = (stat _)[3] - 2
751 or return $grp->result ([], $entries); 758 or return $grp->result ([], $entries);
752 } 759 }
753 760
754 # sort into likely dirs and likely nondirs 761 # sort into likely dirs and likely nondirs
755 # dirs == files without ".", short entries first 762 # dirs == files without ".", short entries first
756 $entries = [map $_->[0], 763 $entries = [map $_->[0],
757 sort { $b->[1] cmp $a->[1] } 764 sort { $b->[1] cmp $a->[1] }
758 map [$_, sprintf "%s%04d", (/.\./ ? "1" : "0"), length], 765 map [$_, sprintf "%s%04d", (/.\./ ? "1" : "0"), length],
759 @$entries]; 766 @$entries];
760 767
761 my (@dirs, @nondirs); 768 my (@dirs, @nondirs);
762 769
763 my $statgrp = add $grp aio_group sub { 770 my $statgrp = add $grp aio_group sub {
764 $grp->result (\@dirs, \@nondirs); 771 $grp->result (\@dirs, \@nondirs);
765 }; 772 };
766 773
767 limit $statgrp $maxreq; 774 limit $statgrp $maxreq;
768 feed $statgrp sub { 775 feed $statgrp sub {
769 return unless @$entries; 776 return unless @$entries;
770 my $entry = pop @$entries; 777 my $entry = pop @$entries;
771 778
772 aioreq_pri $pri; 779 aioreq_pri $pri;
773 add $statgrp aio_stat "$path/$entry/.", sub { 780 add $statgrp aio_stat "$path/$entry/.", sub {
774 if ($_[0] < 0) { 781 if ($_[0] < 0) {
775 push @nondirs, $entry; 782 push @nondirs, $entry;
776 } else { 783 } else {
777 # need to check for real directory 784 # need to check for real directory
778 aioreq_pri $pri; 785 aioreq_pri $pri;
779 add $statgrp aio_lstat "$path/$entry", sub { 786 add $statgrp aio_lstat "$path/$entry", sub {
780 if (-d _) { 787 if (-d _) {
781 push @dirs, $entry; 788 push @dirs, $entry;
782 789
783 unless (--$ndirs) { 790 unless (--$ndirs) {
784 push @nondirs, @$entries; 791 push @nondirs, @$entries;
785 feed $statgrp; 792 feed $statgrp;
786 }
787 } else {
788 push @nondirs, $entry;
789 } 793 }
794 } else {
795 push @nondirs, $entry;
790 } 796 }
791 } 797 }
792 }; 798 }
793 }; 799 };
794 }; 800 };
795 }; 801 };
796 }; 802 };
797
798 $grp
799 } 803 };
804
805 $grp
800} 806}
801 807
802=item aio_rmtree $path, $callback->($status) 808=item aio_rmtree $path, $callback->($status)
803 809
804Delete a directory tree starting (and including) C<$path>, return the 810Delete a directory tree starting (and including) C<$path>, return the
808 814
809=cut 815=cut
810 816
811sub aio_rmtree; 817sub aio_rmtree;
812sub aio_rmtree($;$) { 818sub aio_rmtree($;$) {
813 aio_block {
814 my ($path, $cb) = @_; 819 my ($path, $cb) = @_;
815 820
816 my $pri = aioreq_pri; 821 my $pri = aioreq_pri;
817 my $grp = aio_group $cb; 822 my $grp = aio_group $cb;
818 823
819 aioreq_pri $pri; 824 aioreq_pri $pri;
820 add $grp aio_scandir $path, 0, sub { 825 add $grp aio_scandir $path, 0, sub {
821 my ($dirs, $nondirs) = @_; 826 my ($dirs, $nondirs) = @_;
822 827
823 my $dirgrp = aio_group sub { 828 my $dirgrp = aio_group sub {
824 add $grp aio_rmdir $path, sub { 829 add $grp aio_rmdir $path, sub {
825 $grp->result ($_[0]); 830 $grp->result ($_[0]);
826 };
827 }; 831 };
828
829 (aioreq_pri $pri), add $dirgrp aio_rmtree "$path/$_" for @$dirs;
830 (aioreq_pri $pri), add $dirgrp aio_unlink "$path/$_" for @$nondirs;
831
832 add $grp $dirgrp;
833 }; 832 };
834 833
835 $grp 834 (aioreq_pri $pri), add $dirgrp aio_rmtree "$path/$_" for @$dirs;
835 (aioreq_pri $pri), add $dirgrp aio_unlink "$path/$_" for @$nondirs;
836
837 add $grp $dirgrp;
836 } 838 };
839
840 $grp
837} 841}
842
843=item aio_sync $callback->($status)
844
845Asynchronously call sync and call the callback when finished.
838 846
839=item aio_fsync $fh, $callback->($status) 847=item aio_fsync $fh, $callback->($status)
840 848
841Asynchronously call fsync on the given filehandle and call the callback 849Asynchronously call fsync on the given filehandle and call the callback
842with the fsync result code. 850with the fsync result code.
846Asynchronously call fdatasync on the given filehandle and call the 854Asynchronously call fdatasync on the given filehandle and call the
847callback with the fdatasync result code. 855callback with the fdatasync result code.
848 856
849If this call isn't available because your OS lacks it or it couldn't be 857If this call isn't available because your OS lacks it or it couldn't be
850detected, it will be emulated by calling C<fsync> instead. 858detected, it will be emulated by calling C<fsync> instead.
859
860=item aio_pathsync $path, $callback->($status)
861
862This request tries to open, fsync and close the given path. This is a
863composite request intended tosync directories after directory operations
864(E.g. rename). This might not work on all operating systems or have any
865specific effect, but usually it makes sure that directory changes get
866written to disc. It works for anything that can be opened for read-only,
867not just directories.
868
869Passes C<0> when everything went ok, and C<-1> on error.
870
871=cut
872
873sub aio_pathsync($;$) {
874 my ($path, $cb) = @_;
875
876 my $pri = aioreq_pri;
877 my $grp = aio_group $cb;
878
879 aioreq_pri $pri;
880 add $grp aio_open $path, O_RDONLY, 0, sub {
881 my ($fh) = @_;
882 if ($fh) {
883 aioreq_pri $pri;
884 add $grp aio_fsync $fh, sub {
885 $grp->result ($_[0]);
886
887 aioreq_pri $pri;
888 add $grp aio_close $fh;
889 };
890 } else {
891 $grp->result (-1);
892 }
893 };
894
895 $grp
896}
851 897
852=item aio_group $callback->(...) 898=item aio_group $callback->(...)
853 899
854This is a very special aio request: Instead of doing something, it is a 900This is a very special aio request: Instead of doing something, it is a
855container for other aio requests, which is useful if you want to bundle 901container for other aio requests, which is useful if you want to bundle
992itself. Useful when you queued a lot of events but got a result early. 1038itself. Useful when you queued a lot of events but got a result early.
993 1039
994=item $grp->result (...) 1040=item $grp->result (...)
995 1041
996Set the result value(s) that will be passed to the group callback when all 1042Set the result value(s) that will be passed to the group callback when all
997subrequests have finished and set thre groups errno to the current value 1043subrequests have finished and set the groups errno to the current value
998of errno (just like calling C<errno> without an error number). By default, 1044of errno (just like calling C<errno> without an error number). By default,
999no argument will be passed and errno is zero. 1045no argument will be passed and errno is zero.
1000 1046
1001=item $grp->errno ([$errno]) 1047=item $grp->errno ([$errno])
1002 1048
1071See C<poll_cb> for an example. 1117See C<poll_cb> for an example.
1072 1118
1073=item IO::AIO::poll_cb 1119=item IO::AIO::poll_cb
1074 1120
1075Process some outstanding events on the result pipe. You have to call this 1121Process some outstanding events on the result pipe. You have to call this
1076regularly. Returns the number of events processed. Returns immediately 1122regularly. Returns C<0> if all events could be processed, or C<-1> if it
1123returned earlier for whatever reason. Returns immediately when no events
1077when no events are outstanding. The amount of events processed depends on 1124are outstanding. The amount of events processed depends on the settings of
1078the settings of C<IO::AIO::max_poll_req> and C<IO::AIO::max_poll_time>. 1125C<IO::AIO::max_poll_req> and C<IO::AIO::max_poll_time>.
1079 1126
1080If not all requests were processed for whatever reason, the filehandle 1127If not all requests were processed for whatever reason, the filehandle
1081will still be ready when C<poll_cb> returns. 1128will still be ready when C<poll_cb> returns, so normally you don't have to
1129do anything special to have it called later.
1082 1130
1083Example: Install an Event watcher that automatically calls 1131Example: Install an Event watcher that automatically calls
1084IO::AIO::poll_cb with high priority: 1132IO::AIO::poll_cb with high priority:
1085 1133
1086 Event->io (fd => IO::AIO::poll_fileno, 1134 Event->io (fd => IO::AIO::poll_fileno,
1200 1248
1201The default is probably ok in most situations, especially if thread 1249The default is probably ok in most situations, especially if thread
1202creation is fast. If thread creation is very slow on your system you might 1250creation is fast. If thread creation is very slow on your system you might
1203want to use larger values. 1251want to use larger values.
1204 1252
1205=item $oldmaxreqs = IO::AIO::max_outstanding $maxreqs 1253=item IO::AIO::max_outstanding $maxreqs
1206 1254
1207This is a very bad function to use in interactive programs because it 1255This is a very bad function to use in interactive programs because it
1208blocks, and a bad way to reduce concurrency because it is inexact: Better 1256blocks, and a bad way to reduce concurrency because it is inexact: Better
1209use an C<aio_group> together with a feed callback. 1257use an C<aio_group> together with a feed callback.
1210 1258
1215 1263
1216The default value is very large, so there is no practical limit on the 1264The default value is very large, so there is no practical limit on the
1217number of outstanding requests. 1265number of outstanding requests.
1218 1266
1219You can still queue as many requests as you want. Therefore, 1267You can still queue as many requests as you want. Therefore,
1220C<max_oustsanding> is mainly useful in simple scripts (with low values) or 1268C<max_outstanding> is mainly useful in simple scripts (with low values) or
1221as a stop gap to shield against fatal memory overflow (with large values). 1269as a stop gap to shield against fatal memory overflow (with large values).
1222 1270
1223=back 1271=back
1224 1272
1225=head3 STATISTICAL INFORMATION 1273=head3 STATISTICAL INFORMATION
1247but not yet processed by poll_cb). 1295but not yet processed by poll_cb).
1248 1296
1249=back 1297=back
1250 1298
1251=cut 1299=cut
1252
1253# support function to convert a fd into a perl filehandle
1254sub _fd2fh {
1255 return undef if $_[0] < 0;
1256
1257 # try to generate nice filehandles
1258 my $sym = "IO::AIO::fd#$_[0]";
1259 local *$sym;
1260
1261 open *$sym, "+<&=$_[0]" # usually works under any unix
1262 or open *$sym, "<&=$_[0]" # cygwin needs this
1263 or open *$sym, ">&=$_[0]" # or this
1264 or return undef;
1265
1266 *$sym
1267}
1268 1300
1269min_parallel 8; 1301min_parallel 8;
1270 1302
1271END { flush } 1303END { flush }
1272 1304
1311 1343
1312Known bugs will be fixed in the next release. 1344Known bugs will be fixed in the next release.
1313 1345
1314=head1 SEE ALSO 1346=head1 SEE ALSO
1315 1347
1316L<Coro::AIO>. 1348L<AnyEvent::AIO> for easy integration into event loops, L<Coro::AIO> for a
1349more natural syntax.
1317 1350
1318=head1 AUTHOR 1351=head1 AUTHOR
1319 1352
1320 Marc Lehmann <schmorp@schmorp.de> 1353 Marc Lehmann <schmorp@schmorp.de>
1321 http://home.schmorp.de/ 1354 http://home.schmorp.de/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines