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.50 by root, Sat Jun 24 16:27:02 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines