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.42 by root, Mon Dec 26 18:15:23 2005 UTC vs.
Revision 1.51 by root, Sat Jun 24 19:14:04 2006 UTC

61=cut 61=cut
62 62
63package IO::AIO; 63package IO::AIO;
64 64
65no warnings; 65no warnings;
66use strict 'vars';
66 67
67use base 'Exporter'; 68use base 'Exporter';
68 69
69use Fcntl ();
70
71BEGIN { 70BEGIN {
72 $VERSION = '1.61'; 71 our $VERSION = '1.8';
73 72
74 @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
75 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
76 aio_fsync aio_fdatasync aio_readahead); 75 aio_fsync aio_fdatasync aio_readahead aio_rename aio_link aio_move);
77 @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);
78 max_outstanding nreqs);
79 77
80 require XSLoader; 78 require XSLoader;
81 XSLoader::load IO::AIO, $VERSION; 79 XSLoader::load ("IO::AIO", $VERSION);
82} 80}
83 81
84=head1 FUNCTIONS 82=head1 FUNCTIONS
85 83
86=head2 AIO FUNCTIONS 84=head2 AIO FUNCTIONS
168 aio_read $fh, 7, 15, $buffer, 0, sub { 166 aio_read $fh, 7, 15, $buffer, 0, sub {
169 $_[0] > 0 or die "read error: $!"; 167 $_[0] > 0 or die "read error: $!";
170 print "read $_[0] bytes: <$buffer>\n"; 168 print "read $_[0] bytes: <$buffer>\n";
171 }; 169 };
172 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
173=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)
174 237
175Tries 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
176reading 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
177file 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
232=item aio_unlink $pathname, $callback->($status) 295=item aio_unlink $pathname, $callback->($status)
233 296
234Asynchronously unlink (delete) a file and call the callback with the 297Asynchronously unlink (delete) a file and call the callback with the
235result code. 298result code.
236 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
237=item aio_rmdir $pathname, $callback->($status) 315=item aio_rmdir $pathname, $callback->($status)
238 316
239Asynchronously rmdir (delete) a directory and call the callback with the 317Asynchronously rmdir (delete) a directory and call the callback with the
240result code. 318result code.
241 319
242=item aio_readdir $pathname $callback->($entries) 320=item aio_readdir $pathname, $callback->($entries)
243 321
244Unlike 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
245directory (i.e. opendir + readdir + closedir). The entries will not be 323directory (i.e. opendir + readdir + closedir). The entries will not be
246sorted, and will B<NOT> include the C<.> and C<..> entries. 324sorted, and will B<NOT> include the C<.> and C<..> entries.
247 325
282 360
283Then entires will be sorted into likely directories (everything without a 361Then entires will be sorted into likely directories (everything without a
284non-initial dot) and likely non-directories (everything else). Then every 362non-initial dot) and likely non-directories (everything else). Then every
285entry + 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
286faster because filesystems might detect the type of the entry without 364faster because filesystems might detect the type of the entry without
287reading the inode data (e.g. ext2s filetype feature). If that succeeds, 365reading the inode data (e.g. ext2fs filetype feature). If that succeeds,
288it 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
289will be checked seperately). 367will be checked seperately).
290 368
291If 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
292entries is assumed to be non-directories. 370entries is assumed to be non-directories.
298 376
299 $maxreq = 8 if $maxreq <= 0; 377 $maxreq = 8 if $maxreq <= 0;
300 378
301 # stat once 379 # stat once
302 aio_stat $path, sub { 380 aio_stat $path, sub {
303 $cb->() if $_[0]; 381 return $cb->() if $_[0];
304 my $hash1 = join ":", (stat _)[0,1,3,7,9]; 382 my $hash1 = join ":", (stat _)[0,1,3,7,9];
305 383
306 # read the directory entries 384 # read the directory entries
307 aio_readdir $path, sub { 385 aio_readdir $path, sub {
308 my $entries = shift 386 my $entries = shift
319 $ndirs = -1; 397 $ndirs = -1;
320 } else { 398 } else {
321 # if nlink == 2, we are finished 399 # if nlink == 2, we are finished
322 # on non-posix-fs's, we rely on nlink < 2 400 # on non-posix-fs's, we rely on nlink < 2
323 $ndirs = (stat _)[3] - 2 401 $ndirs = (stat _)[3] - 2
324 or $cb->([], $entries); 402 or return $cb->([], $entries);
325 } 403 }
326 404
327 # sort into likely dirs and likely nondirs 405 # sort into likely dirs and likely nondirs
328 # dirs == files without ".", short entries first 406 # dirs == files without ".", short entries first
329 $entries = [map $_->[0], 407 $entries = [map $_->[0],
345 } 423 }
346 } elsif (!$nreq) { 424 } elsif (!$nreq) {
347 # finished 425 # finished
348 undef $statcb; 426 undef $statcb;
349 undef $schedcb; 427 undef $schedcb;
350 $cb->(\@dirs, \@nondirs); 428 $cb->(\@dirs, \@nondirs) if $cb;
351 undef $cb; 429 undef $cb;
352 } 430 }
353 }; 431 };
354 $statcb = sub { 432 $statcb = sub {
355 my ($status, $entry) = @_; 433 my ($status, $entry) = @_;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines