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.84 by root, Sat Oct 28 00:17:30 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).
337
338The only portable (POSIX) way of calling this function is:
339
340 aio_mknod $path, IO::AIO::S_IFIFO | $mode, 0, sub { ...
341
409=item aio_link $srcpath, $dstpath, $callback->($status) 342=item aio_link $srcpath, $dstpath, $callback->($status)
410 343
411Asynchronously create a new link to the existing object at C<$srcpath> at 344Asynchronously create a new link to the existing object at C<$srcpath> at
412the path C<$dstpath> and call the callback with the result code. 345the path C<$dstpath> and call the callback with the result code.
413 346
432directory (i.e. opendir + readdir + closedir). The entries will not be 365directory (i.e. opendir + readdir + closedir). The entries will not be
433sorted, and will B<NOT> include the C<.> and C<..> entries. 366sorted, and will B<NOT> include the C<.> and C<..> entries.
434 367
435The callback a single argument which is either C<undef> or an array-ref 368The callback a single argument which is either C<undef> or an array-ref
436with the filenames. 369with the filenames.
370
371=item aio_copy $srcpath, $dstpath, $callback->($status)
372
373Try to copy the I<file> (directories not supported as either source or
374destination) from C<$srcpath> to C<$dstpath> and call the callback with
375the C<0> (error) or C<-1> ok.
376
377This is a composite request that it creates the destination file with
378mode 0200 and copies the contents of the source file into it using
379C<aio_sendfile>, followed by restoring atime, mtime, access mode and
380uid/gid, in that order.
381
382If an error occurs, the partial destination file will be unlinked, if
383possible, except when setting atime, mtime, access mode and uid/gid, where
384errors are being ignored.
385
386=cut
387
388sub aio_copy($$;$) {
389 my ($src, $dst, $cb) = @_;
390
391 my $pri = aioreq_pri;
392 my $grp = aio_group $cb;
393
394 aioreq_pri $pri;
395 add $grp aio_open $src, O_RDONLY, 0, sub {
396 if (my $src_fh = $_[0]) {
397 my @stat = stat $src_fh;
398
399 aioreq_pri $pri;
400 add $grp aio_open $dst, O_CREAT | O_WRONLY | O_TRUNC, 0200, sub {
401 if (my $dst_fh = $_[0]) {
402 aioreq_pri $pri;
403 add $grp aio_sendfile $dst_fh, $src_fh, 0, $stat[7], sub {
404 if ($_[0] == $stat[7]) {
405 $grp->result (0);
406 close $src_fh;
407
408 # those should not normally block. should. should.
409 utime $stat[8], $stat[9], $dst;
410 chmod $stat[2] & 07777, $dst_fh;
411 chown $stat[4], $stat[5], $dst_fh;
412 close $dst_fh;
413 } else {
414 $grp->result (-1);
415 close $src_fh;
416 close $dst_fh;
417
418 aioreq $pri;
419 add $grp aio_unlink $dst;
420 }
421 };
422 } else {
423 $grp->result (-1);
424 }
425 },
426
427 } else {
428 $grp->result (-1);
429 }
430 };
431
432 $grp
433}
434
435=item aio_move $srcpath, $dstpath, $callback->($status)
436
437Try to move the I<file> (directories not supported as either source or
438destination) from C<$srcpath> to C<$dstpath> and call the callback with
439the C<0> (error) or C<-1> ok.
440
441This is a composite request that tries to rename(2) the file first. If
442rename files with C<EXDEV>, it copies the file with C<aio_copy> and, if
443that is successful, unlinking the C<$srcpath>.
444
445=cut
446
447sub aio_move($$;$) {
448 my ($src, $dst, $cb) = @_;
449
450 my $pri = aioreq_pri;
451 my $grp = aio_group $cb;
452
453 aioreq_pri $pri;
454 add $grp aio_rename $src, $dst, sub {
455 if ($_[0] && $! == EXDEV) {
456 aioreq_pri $pri;
457 add $grp aio_copy $src, $dst, sub {
458 $grp->result ($_[0]);
459
460 if (!$_[0]) {
461 aioreq_pri $pri;
462 add $grp aio_unlink $src;
463 }
464 };
465 } else {
466 $grp->result ($_[0]);
467 }
468 };
469
470 $grp
471}
437 472
438=item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs) 473=item aio_scandir $path, $maxreq, $callback->($dirs, $nondirs)
439 474
440Scans a directory (similar to C<aio_readdir>) but additionally tries to 475Scans a directory (similar to C<aio_readdir>) but additionally tries to
441efficiently separate the entries of directory C<$path> into two sets of 476efficiently separate the entries of directory C<$path> into two sets of
443recurse into (everything else, including symlinks to directories). 478recurse into (everything else, including symlinks to directories).
444 479
445C<aio_scandir> is a composite request that creates of many sub requests_ 480C<aio_scandir> is a composite request that creates of many sub requests_
446C<$maxreq> specifies the maximum number of outstanding aio requests that 481C<$maxreq> specifies the maximum number of outstanding aio requests that
447this function generates. If it is C<< <= 0 >>, then a suitable default 482this function generates. If it is C<< <= 0 >>, then a suitable default
448will be chosen (currently 6). 483will be chosen (currently 4).
449 484
450On error, the callback is called without arguments, otherwise it receives 485On error, the callback is called without arguments, otherwise it receives
451two array-refs with path-relative entry names. 486two array-refs with path-relative entry names.
452 487
453Example: 488Example:
494 529
495 my $pri = aioreq_pri; 530 my $pri = aioreq_pri;
496 531
497 my $grp = aio_group $cb; 532 my $grp = aio_group $cb;
498 533
499 $maxreq = 6 if $maxreq <= 0; 534 $maxreq = 4 if $maxreq <= 0;
500 535
501 # stat once 536 # stat once
502 aioreq_pri $pri; 537 aioreq_pri $pri;
503 add $grp aio_stat $path, sub { 538 add $grp aio_stat $path, sub {
504 return $grp->result () if $_[0]; 539 return $grp->result () if $_[0];
956} 991}
957 992
958min_parallel 8; 993min_parallel 8;
959 994
960END { 995END {
961 max_parallel 0; 996 min_parallel 1;
962} 997 flush;
998};
963 999
9641; 10001;
965 1001
966=head2 FORK BEHAVIOUR 1002=head2 FORK BEHAVIOUR
967 1003

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines