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.81 by root, Fri Oct 27 19:17:23 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
955 *$sym 988 *$sym
956} 989}
957 990
958min_parallel 8; 991min_parallel 8;
959 992
993END {
994 flush;
995};
996
9601; 9971;
961 998
962=head2 FORK BEHAVIOUR 999=head2 FORK BEHAVIOUR
963 1000
964This module should do "the right thing" when the process using it forks: 1001This module should do "the right thing" when the process using it forks:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines