… | |
… | |
966 | |
966 | |
967 | my $grp = aio_group $cb; |
967 | my $grp = aio_group $cb; |
968 | |
968 | |
969 | $maxreq = 4 if $maxreq <= 0; |
969 | $maxreq = 4 if $maxreq <= 0; |
970 | |
970 | |
971 | # stat once |
971 | # get a wd object |
|
|
972 | |
972 | aioreq_pri $pri; |
973 | aioreq_pri $pri; |
973 | add $grp aio_stat $path, sub { |
974 | add $grp aio_wd $path, sub { |
974 | return $grp->result () if $_[0]; |
975 | my $wd = [shift, "."]; |
975 | my $now = time; |
|
|
976 | my $hash1 = join ":", (stat _)[0,1,3,7,9]; |
|
|
977 | |
976 | |
978 | # read the directory entries |
977 | # stat once |
979 | aioreq_pri $pri; |
978 | aioreq_pri $pri; |
980 | add $grp aio_readdirx $path, READDIR_DIRS_FIRST, sub { |
979 | add $grp aio_stat $wd, sub { |
981 | my $entries = shift |
|
|
982 | or return $grp->result (); |
980 | return $grp->result () if $_[0]; |
|
|
981 | my $now = time; |
|
|
982 | my $hash1 = join ":", (stat _)[0,1,3,7,9]; |
983 | |
983 | |
984 | # stat the dir another time |
984 | # read the directory entries |
985 | aioreq_pri $pri; |
985 | aioreq_pri $pri; |
|
|
986 | add $grp aio_readdirx $wd, READDIR_DIRS_FIRST, sub { |
|
|
987 | my $entries = shift |
|
|
988 | or return $grp->result (); |
|
|
989 | |
|
|
990 | # stat the dir another time |
|
|
991 | aioreq_pri $pri; |
986 | add $grp aio_stat $path, sub { |
992 | add $grp aio_stat $wd, sub { |
987 | my $hash2 = join ":", (stat _)[0,1,3,7,9]; |
993 | my $hash2 = join ":", (stat _)[0,1,3,7,9]; |
988 | |
994 | |
989 | my $ndirs; |
995 | my $ndirs; |
990 | |
996 | |
991 | # take the slow route if anything looks fishy |
997 | # take the slow route if anything looks fishy |
992 | if ($hash1 ne $hash2 or (stat _)[9] == $now) { |
998 | if ($hash1 ne $hash2 or (stat _)[9] == $now) { |
993 | $ndirs = -1; |
999 | $ndirs = -1; |
994 | } else { |
1000 | } else { |
995 | # if nlink == 2, we are finished |
1001 | # if nlink == 2, we are finished |
996 | # for non-posix-fs's, we rely on nlink < 2 |
1002 | # for non-posix-fs's, we rely on nlink < 2 |
997 | $ndirs = (stat _)[3] - 2 |
1003 | $ndirs = (stat _)[3] - 2 |
998 | or return $grp->result ([], $entries); |
1004 | or return $grp->result ([], $entries); |
999 | } |
1005 | } |
1000 | |
1006 | |
1001 | my (@dirs, @nondirs); |
1007 | my (@dirs, @nondirs); |
1002 | |
1008 | |
1003 | my $statgrp = add $grp aio_group sub { |
1009 | my $statgrp = add $grp aio_group sub { |
1004 | $grp->result (\@dirs, \@nondirs); |
1010 | $grp->result (\@dirs, \@nondirs); |
1005 | }; |
1011 | }; |
1006 | |
1012 | |
1007 | limit $statgrp $maxreq; |
1013 | limit $statgrp $maxreq; |
1008 | feed $statgrp sub { |
1014 | feed $statgrp sub { |
1009 | return unless @$entries; |
1015 | return unless @$entries; |
1010 | my $entry = shift @$entries; |
1016 | my $entry = shift @$entries; |
1011 | |
1017 | |
1012 | aioreq_pri $pri; |
1018 | aioreq_pri $pri; |
|
|
1019 | $wd->[1] = "$entry/."; |
1013 | add $statgrp aio_stat "$path/$entry/.", sub { |
1020 | add $statgrp aio_stat $wd, sub { |
1014 | if ($_[0] < 0) { |
1021 | if ($_[0] < 0) { |
1015 | push @nondirs, $entry; |
1022 | push @nondirs, $entry; |
1016 | } else { |
1023 | } else { |
1017 | # need to check for real directory |
1024 | # need to check for real directory |
1018 | aioreq_pri $pri; |
1025 | aioreq_pri $pri; |
|
|
1026 | $wd->[1] = $entry; |
1019 | add $statgrp aio_lstat "$path/$entry", sub { |
1027 | add $statgrp aio_lstat $wd, sub { |
1020 | if (-d _) { |
1028 | if (-d _) { |
1021 | push @dirs, $entry; |
1029 | push @dirs, $entry; |
1022 | |
1030 | |
1023 | unless (--$ndirs) { |
1031 | unless (--$ndirs) { |
1024 | push @nondirs, @$entries; |
1032 | push @nondirs, @$entries; |
1025 | feed $statgrp; |
1033 | feed $statgrp; |
|
|
1034 | } |
|
|
1035 | } else { |
|
|
1036 | push @nondirs, $entry; |
1026 | } |
1037 | } |
1027 | } else { |
|
|
1028 | push @nondirs, $entry; |
|
|
1029 | } |
1038 | } |
1030 | } |
1039 | } |
1031 | } |
1040 | }; |
1032 | }; |
1041 | }; |
1033 | }; |
1042 | }; |
1034 | }; |
1043 | }; |
1035 | }; |
1044 | }; |
1036 | }; |
1045 | }; |