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.41 by root, Wed Sep 7 17:41:17 2005 UTC vs.
Revision 1.51 by root, Sat Jun 24 19:14:04 2006 UTC

14 aio_unlink "/tmp/file", sub { }; 14 aio_unlink "/tmp/file", sub { };
15 15
16 aio_read $fh, 30000, 1024, $buffer, 0, sub { 16 aio_read $fh, 30000, 1024, $buffer, 0, sub {
17 $_[0] > 0 or die "read error: $!"; 17 $_[0] > 0 or die "read error: $!";
18 }; 18 };
19
20 # AnyEvent
21 open my $fh, "<&=" . IO::AIO::poll_fileno or die "$!";
22 my $w = AnyEvent->io (fh => $fh, poll => 'r', cb => sub { IO::AIO::poll_cb });
19 23
20 # Event 24 # Event
21 Event->io (fd => IO::AIO::poll_fileno, 25 Event->io (fd => IO::AIO::poll_fileno,
22 poll => 'r', 26 poll => 'r',
23 cb => \&IO::AIO::poll_cb); 27 cb => \&IO::AIO::poll_cb);
57=cut 61=cut
58 62
59package IO::AIO; 63package IO::AIO;
60 64
61no warnings; 65no warnings;
66use strict 'vars';
62 67
63use base 'Exporter'; 68use base 'Exporter';
64 69
65use Fcntl ();
66
67BEGIN { 70BEGIN {
68 $VERSION = '1.61'; 71 our $VERSION = '1.8';
69 72
70 @EXPORT = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat 73 our @EXPORT = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat
71 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink 74 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink
72 aio_fsync aio_fdatasync aio_readahead); 75 aio_fsync aio_fdatasync aio_readahead aio_rename aio_link aio_move);
73 @EXPORT_OK = qw(poll_fileno poll_cb min_parallel max_parallel 76 our @EXPORT_OK = qw(poll_fileno poll_cb min_parallel max_parallel max_outstanding nreqs);
74 max_outstanding nreqs);
75 77
76 require XSLoader; 78 require XSLoader;
77 XSLoader::load IO::AIO, $VERSION; 79 XSLoader::load ("IO::AIO", $VERSION);
78} 80}
79 81
80=head1 FUNCTIONS 82=head1 FUNCTIONS
81 83
82=head2 AIO FUNCTIONS 84=head2 AIO FUNCTIONS
164 aio_read $fh, 7, 15, $buffer, 0, sub { 166 aio_read $fh, 7, 15, $buffer, 0, sub {
165 $_[0] > 0 or die "read error: $!"; 167 $_[0] > 0 or die "read error: $!";
166 print "read $_[0] bytes: <$buffer>\n"; 168 print "read $_[0] bytes: <$buffer>\n";
167 }; 169 };
168 170
171=item aio_move $srcpath, $dstpath, $callback->($status)
172
173[EXPERIMENTAL]
174
175Try to move the I<file> (directories not supported as either source or destination)
176from C<$srcpath> to C<$dstpath> and call the callback with the C<0> (error) or C<-1> ok.
177
178This is a composite request that tries to rename(2) the file first. If
179rename files with C<EXDEV>, it creates the destination file with mode 0200
180and copies the contents of the source file into it using C<aio_sendfile>,
181followed by restoring atime, mtime, access mode and uid/gid, in that
182order, and unlinking the C<$srcpath>.
183
184If an error occurs, the partial destination file will be unlinked, if
185possible, except when setting atime, mtime, access mode and uid/gid, where
186errors are being ignored.
187
188=cut
189
190sub aio_move($$$) {
191 my ($src, $dst, $cb) = @_;
192
193 aio_rename $src, $dst, sub {
194 if ($_[0] && $! == EXDEV) {
195 aio_open $src, O_RDONLY, 0, sub {
196 if (my $src_fh = $_[0]) {
197 my @stat = stat $src_fh;
198
199 aio_open $dst, O_WRONLY, 0200, sub {
200 if (my $dst_fh = $_[0]) {
201 aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub {
202 close $src_fh;
203
204 if ($_[0] == $stat[7]) {
205 utime $stat[8], $stat[9], $dst;
206 chmod $stat[2] & 07777, $dst_fh;
207 chown $stat[4], $stat[5], $dst_fh;
208 close $dst_fh;
209
210 aio_unlink $src, sub {
211 $cb->($_[0]);
212 };
213 } else {
214 my $errno = $!;
215 aio_unlink $dst, sub {
216 $! = $errno;
217 $cb->(-1);
218 };
219 }
220 };
221 } else {
222 $cb->(-1);
223 }
224 },
225
226 } else {
227 $cb->(-1);
228 }
229 };
230 } else {
231 $cb->($_[0]);
232 }
233 };
234}
235
169=item aio_sendfile $out_fh, $in_fh, $in_offset, $length, $callback->($retval) 236=item aio_sendfile $out_fh, $in_fh, $in_offset, $length, $callback->($retval)
170 237
171Tries to copy C<$length> bytes from C<$in_fh> to C<$out_fh>. It starts 238Tries to copy C<$length> bytes from C<$in_fh> to C<$out_fh>. It starts
172reading at byte offset C<$in_offset>, and starts writing at the current 239reading at byte offset C<$in_offset>, and starts writing at the current
173file offset of C<$out_fh>. Because of that, it is not safe to issue more 240file offset of C<$out_fh>. Because of that, it is not safe to issue more
228=item aio_unlink $pathname, $callback->($status) 295=item aio_unlink $pathname, $callback->($status)
229 296
230Asynchronously unlink (delete) a file and call the callback with the 297Asynchronously unlink (delete) a file and call the callback with the
231result code. 298result code.
232 299
300=item aio_link $srcpath, $dstpath, $callback->($status)
301
302Asynchronously create a new link to the existing object at C<$srcpath> at
303the path C<$dstpath> and call the callback with the result code.
304
305=item aio_symlink $srcpath, $dstpath, $callback->($status)
306
307Asynchronously create a new symbolic link to the existing object at C<$srcpath> at
308the path C<$dstpath> and call the callback with the result code.
309
310=item aio_rename $srcpath, $dstpath, $callback->($status)
311
312Asynchronously rename the object at C<$srcpath> to C<$dstpath>, just as
313rename(2) and call the callback with the result code.
314
233=item aio_rmdir $pathname, $callback->($status) 315=item aio_rmdir $pathname, $callback->($status)
234 316
235Asynchronously rmdir (delete) a directory and call the callback with the 317Asynchronously rmdir (delete) a directory and call the callback with the
236result code. 318result code.
237 319
238=item aio_readdir $pathname $callback->($entries) 320=item aio_readdir $pathname, $callback->($entries)
239 321
240Unlike the POSIX call of the same name, C<aio_readdir> reads an entire 322Unlike the POSIX call of the same name, C<aio_readdir> reads an entire
241directory (i.e. opendir + readdir + closedir). The entries will not be 323directory (i.e. opendir + readdir + closedir). The entries will not be
242sorted, and will B<NOT> include the C<.> and C<..> entries. 324sorted, and will B<NOT> include the C<.> and C<..> entries.
243 325
278 360
279Then entires will be sorted into likely directories (everything without a 361Then entires will be sorted into likely directories (everything without a
280non-initial dot) and likely non-directories (everything else). Then every 362non-initial dot) and likely non-directories (everything else). Then every
281entry + C</.> will be C<stat>'ed, likely directories first. This is often 363entry + C</.> will be C<stat>'ed, likely directories first. This is often
282faster because filesystems might detect the type of the entry without 364faster because filesystems might detect the type of the entry without
283reading the inode data (e.g. ext2s filetype feature). If that succeeds, 365reading the inode data (e.g. ext2fs filetype feature). If that succeeds,
284it assumes that the entry is a directory or a symlink to directory (which 366it assumes that the entry is a directory or a symlink to directory (which
285will be checked seperately). 367will be checked seperately).
286 368
287If the known number of directories has been reached, the rest of the 369If the known number of directories has been reached, the rest of the
288entries is assumed to be non-directories. 370entries is assumed to be non-directories.
294 376
295 $maxreq = 8 if $maxreq <= 0; 377 $maxreq = 8 if $maxreq <= 0;
296 378
297 # stat once 379 # stat once
298 aio_stat $path, sub { 380 aio_stat $path, sub {
299 $cb->() if $_[0]; 381 return $cb->() if $_[0];
300 my $hash1 = join ":", (stat _)[0,1,3,7,9]; 382 my $hash1 = join ":", (stat _)[0,1,3,7,9];
301 383
302 # read the directory entries 384 # read the directory entries
303 aio_readdir $path, sub { 385 aio_readdir $path, sub {
304 my $entries = shift 386 my $entries = shift
315 $ndirs = -1; 397 $ndirs = -1;
316 } else { 398 } else {
317 # if nlink == 2, we are finished 399 # if nlink == 2, we are finished
318 # on non-posix-fs's, we rely on nlink < 2 400 # on non-posix-fs's, we rely on nlink < 2
319 $ndirs = (stat _)[3] - 2 401 $ndirs = (stat _)[3] - 2
320 or $cb->([], $entries); 402 or return $cb->([], $entries);
321 } 403 }
322 404
323 # sort into likely dirs and likely nondirs 405 # sort into likely dirs and likely nondirs
324 # dirs == files without ".", short entries first 406 # dirs == files without ".", short entries first
325 $entries = [map $_->[0], 407 $entries = [map $_->[0],
341 } 423 }
342 } elsif (!$nreq) { 424 } elsif (!$nreq) {
343 # finished 425 # finished
344 undef $statcb; 426 undef $statcb;
345 undef $schedcb; 427 undef $schedcb;
346 $cb->(\@dirs, \@nondirs); 428 $cb->(\@dirs, \@nondirs) if $cb;
347 undef $cb; 429 undef $cb;
348 } 430 }
349 }; 431 };
350 $statcb = sub { 432 $statcb = sub {
351 my ($status, $entry) = @_; 433 my ($status, $entry) = @_;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines