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.80 by root, Thu Oct 26 16:28:33 2006 UTC vs.
Revision 1.82 by root, Fri Oct 27 20:10:06 2006 UTC

131 our $VERSION = '2.0'; 131 our $VERSION = '2.0';
132 132
133 our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat 133 our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat
134 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink 134 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink
135 aio_fsync aio_fdatasync aio_readahead aio_rename aio_link aio_move 135 aio_fsync aio_fdatasync aio_readahead aio_rename aio_link aio_move
136 aio_group aio_nop); 136 aio_copy aio_group aio_nop aio_mknod);
137 our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice)); 137 our @EXPORT = (@AIO_REQ, qw(aioreq_pri aioreq_nice));
138 our @EXPORT_OK = qw(poll_fileno poll_cb poll_wait flush 138 our @EXPORT_OK = qw(poll_fileno poll_cb poll_wait flush
139 min_parallel max_parallel nreqs nready npending); 139 min_parallel max_parallel nreqs nready npending);
140 140
141 @IO::AIO::GRP::ISA = 'IO::AIO::REQ'; 141 @IO::AIO::GRP::ISA = 'IO::AIO::REQ';
264 264
265 aio_read $fh, 7, 15, $buffer, 0, sub { 265 aio_read $fh, 7, 15, $buffer, 0, sub {
266 $_[0] > 0 or die "read error: $!"; 266 $_[0] > 0 or die "read error: $!";
267 print "read $_[0] bytes: <$buffer>\n"; 267 print "read $_[0] bytes: <$buffer>\n";
268 }; 268 };
269
270=item aio_move $srcpath, $dstpath, $callback->($status)
271
272Try to move the I<file> (directories not supported as either source or
273destination) from C<$srcpath> to C<$dstpath> and call the callback with
274the C<0> (error) or C<-1> ok.
275
276This is a composite request that tries to rename(2) the file first. If
277rename files with C<EXDEV>, it creates the destination file with mode 0200
278and copies the contents of the source file into it using C<aio_sendfile>,
279followed by restoring atime, mtime, access mode and uid/gid, in that
280order, and unlinking the C<$srcpath>.
281
282If an error occurs, the partial destination file will be unlinked, if
283possible, except when setting atime, mtime, access mode and uid/gid, where
284errors are being ignored.
285
286=cut
287
288sub aio_move($$$) {
289 my ($src, $dst, $cb) = @_;
290
291 my $pri = aioreq_pri;
292 my $grp = aio_group $cb;
293
294 aioreq_pri $pri;
295 add $grp aio_rename $src, $dst, sub {
296 if ($_[0] && $! == EXDEV) {
297 aioreq_pri $pri;
298 add $grp aio_open $src, O_RDONLY, 0, sub {
299 if (my $src_fh = $_[0]) {
300 my @stat = stat $src_fh;
301
302 aioreq_pri $pri;
303 add $grp aio_open $dst, O_WRONLY, 0200, sub {
304 if (my $dst_fh = $_[0]) {
305 aioreq_pri $pri;
306 add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub {
307 close $src_fh;
308
309 if ($_[0] == $stat[7]) {
310 utime $stat[8], $stat[9], $dst;
311 chmod $stat[2] & 07777, $dst_fh;
312 chown $stat[4], $stat[5], $dst_fh;
313 close $dst_fh;
314
315 aioreq_pri $pri;
316 add $grp aio_unlink $src, sub {
317 $grp->result ($_[0]);
318 };
319 } else {
320 my $errno = $!;
321 aioreq_pri $pri;
322 add $grp aio_unlink $dst, sub {
323 $! = $errno;
324 $grp->result (-1);
325 };
326 }
327 };
328 } else {
329 $grp->result (-1);
330 }
331 },
332
333 } else {
334 $grp->result (-1);
335 }
336 };
337 } else {
338 $grp->result ($_[0]);
339 }
340 };
341
342 $grp
343}
344 269
345=item aio_sendfile $out_fh, $in_fh, $in_offset, $length, $callback->($retval) 270=item aio_sendfile $out_fh, $in_fh, $in_offset, $length, $callback->($retval)
346 271
347Tries to copy C<$length> bytes from C<$in_fh> to C<$out_fh>. It starts 272Tries to copy C<$length> bytes from C<$in_fh> to C<$out_fh>. It starts
348reading at byte offset C<$in_offset>, and starts writing at the current 273reading at byte offset C<$in_offset>, and starts writing at the current
404=item aio_unlink $pathname, $callback->($status) 329=item aio_unlink $pathname, $callback->($status)
405 330
406Asynchronously unlink (delete) a file and call the callback with the 331Asynchronously unlink (delete) a file and call the callback with the
407result code. 332result code.
408 333
334=item aio_mknod $path, $mode, $dev, $callback->($status)
335
336Asynchronously create a device node (or fifo). See mknod(2): the only
337portable value for C<$mode> is C<S_IFIFO> ored with permissions, and C<0>
338for C<$dev>.
339
409=item aio_link $srcpath, $dstpath, $callback->($status) 340=item aio_link $srcpath, $dstpath, $callback->($status)
410 341
411Asynchronously create a new link to the existing object at C<$srcpath> at 342Asynchronously create a new link to the existing object at C<$srcpath> at
412the path C<$dstpath> and call the callback with the result code. 343the path C<$dstpath> and call the callback with the result code.
413 344
432directory (i.e. opendir + readdir + closedir). The entries will not be 363directory (i.e. opendir + readdir + closedir). The entries will not be
433sorted, and will B<NOT> include the C<.> and C<..> entries. 364sorted, and will B<NOT> include the C<.> and C<..> entries.
434 365
435The callback a single argument which is either C<undef> or an array-ref 366The callback a single argument which is either C<undef> or an array-ref
436with the filenames. 367with the filenames.
368
369=item aio_copy $srcpath, $dstpath, $callback->($status)
370
371Try to copy the I<file> (directories not supported as either source or
372destination) from C<$srcpath> to C<$dstpath> and call the callback with
373the C<0> (error) or C<-1> ok.
374
375This is a composite request that it creates the destination file with
376mode 0200 and copies the contents of the source file into it using
377C<aio_sendfile>, followed by restoring atime, mtime, access mode and
378uid/gid, in that order.
379
380If an error occurs, the partial destination file will be unlinked, if
381possible, except when setting atime, mtime, access mode and uid/gid, where
382errors are being ignored.
383
384=cut
385
386sub aio_copy($$;$) {
387 my ($src, $dst, $cb) = @_;
388
389 my $pri = aioreq_pri;
390 my $grp = aio_group $cb;
391
392 aioreq_pri $pri;
393 add $grp aio_open $src, O_RDONLY, 0, sub {
394 if (my $src_fh = $_[0]) {
395 my @stat = stat $src_fh;
396
397 aioreq_pri $pri;
398 add $grp aio_open $dst, O_CREAT | O_WRONLY | O_TRUNC, 0200, sub {
399 if (my $dst_fh = $_[0]) {
400 aioreq_pri $pri;
401 add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub {
402 if ($_[0] == $stat[7]) {
403 $grp->result (0);
404 close $src_fh;
405
406 # those should not normally block. should. should.
407 utime $stat[8], $stat[9], $dst;
408 chmod $stat[2] & 07777, $dst_fh;
409 chown $stat[4], $stat[5], $dst_fh;
410 close $dst_fh;
411 } else {
412 $grp->result (-1);
413 close $src_fh;
414 close $dst_fh;
415
416 aioreq $pri;
417 add $grp aio_unlink $dst;
418 }
419 };
420 } else {
421 $grp->result (-1);
422 }
423 },
424
425 } else {
426 $grp->result (-1);
427 }
428 };
429
430 $grp
431}
432
433=item aio_move $srcpath, $dstpath, $callback->($status)
434
435Try to move the I<file> (directories not supported as either source or
436destination) from C<$srcpath> to C<$dstpath> and call the callback with
437the C<0> (error) or C<-1> ok.
438
439This is a composite request that tries to rename(2) the file first. If
440rename files with C<EXDEV>, it copies the file with C<aio_copy> and, if
441that is successful, unlinking the C<$srcpath>.
442
443=cut
444
445sub aio_move($$;$) {
446 my ($src, $dst, $cb) = @_;
447
448 my $pri = aioreq_pri;
449 my $grp = aio_group $cb;
450
451 aioreq_pri $pri;
452 add $grp aio_rename $src, $dst, sub {
453 if ($_[0] && $! == EXDEV) {
454 aioreq_pri $pri;
455 add $grp aio_copy $src, $dst, sub {
456 $grp->result ($_[0]);
457
458 if (!$_[0]) {
459 aioreq_pri $pri;
460 add $grp aio_unlink $src;
461 }
462 };
463 } else {
464 $grp->result ($_[0]);
465 }
466 };
467
468 $grp
469}
437 470
438=item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs) 471=item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs)
439 472
440Scans a directory (similar to C<aio_readdir>) but additionally tries to 473Scans a directory (similar to C<aio_readdir>) but additionally tries to
441efficiently separate the entries of directory C<$path> into two sets of 474efficiently separate the entries of directory C<$path> into two sets of
443recurse into (everything else, including symlinks to directories). 476recurse into (everything else, including symlinks to directories).
444 477
445C<aio_scandir> is a composite request that creates of many sub requests_ 478C<aio_scandir> is a composite request that creates of many sub requests_
446C<$maxreq> specifies the maximum number of outstanding aio requests that 479C<$maxreq> specifies the maximum number of outstanding aio requests that
447this function generates. If it is C<< <= 0 >>, then a suitable default 480this function generates. If it is C<< <= 0 >>, then a suitable default
448will be chosen (currently 6). 481will be chosen (currently 4).
449 482
450On error, the callback is called without arguments, otherwise it receives 483On error, the callback is called without arguments, otherwise it receives
451two array-refs with path-relative entry names. 484two array-refs with path-relative entry names.
452 485
453Example: 486Example:
494 527
495 my $pri = aioreq_pri; 528 my $pri = aioreq_pri;
496 529
497 my $grp = aio_group $cb; 530 my $grp = aio_group $cb;
498 531
499 $maxreq = 6 if $maxreq <= 0; 532 $maxreq = 4 if $maxreq <= 0;
500 533
501 # stat once 534 # stat once
502 aioreq_pri $pri; 535 aioreq_pri $pri;
503 add $grp aio_stat $path, sub { 536 add $grp aio_stat $path, sub {
504 return $grp->result () if $_[0]; 537 return $grp->result () if $_[0];
956} 989}
957 990
958min_parallel 8; 991min_parallel 8;
959 992
960END { 993END {
961 max_parallel 0; 994 flush;
962} 995};
963 996
9641; 9971;
965 998
966=head2 FORK BEHAVIOUR 999=head2 FORK BEHAVIOUR
967 1000

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines