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.40 by root, Tue Aug 30 15:45:10 2005 UTC vs.
Revision 1.50 by root, Sat Jun 24 16:27:02 2006 UTC

14 aio_unlink "/tmp/file", sub { }; 14 aio_unlink "/tmp/file", sub { };
15 15
16 aio_read $fh, 30000, 1024, $buffer, 0, sub { 16 aio_read $fh, 30000, 1024, $buffer, 0, sub {
17 $_[0] > 0 or die "read error: $!"; 17 $_[0] > 0 or die "read error: $!";
18 }; 18 };
19
20 # AnyEvent
21 open my $fh, "<&=" . IO::AIO::poll_fileno or die "$!";
22 my $w = AnyEvent->io (fh => $fh, poll => 'r', cb => sub { IO::AIO::poll_cb });
19 23
20 # Event 24 # Event
21 Event->io (fd => IO::AIO::poll_fileno, 25 Event->io (fd => IO::AIO::poll_fileno,
22 poll => 'r', 26 poll => 'r',
23 cb => \&IO::AIO::poll_cb); 27 cb => \&IO::AIO::poll_cb);
63use base 'Exporter'; 67use base 'Exporter';
64 68
65use Fcntl (); 69use Fcntl ();
66 70
67BEGIN { 71BEGIN {
68 $VERSION = 1.6; 72 $VERSION = '1.8';
69 73
70 @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
71 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
72 aio_fsync aio_fdatasync aio_readahead); 76 aio_fsync aio_fdatasync aio_readahead aio_rename aio_link aio_move);
73 @EXPORT_OK = qw(poll_fileno poll_cb min_parallel max_parallel 77 @EXPORT_OK = qw(poll_fileno poll_cb min_parallel max_parallel
74 max_outstanding nreqs); 78 max_outstanding nreqs);
75 79
76 require XSLoader; 80 require XSLoader;
77 XSLoader::load IO::AIO, $VERSION; 81 XSLoader::load IO::AIO, $VERSION;
164 aio_read $fh, 7, 15, $buffer, 0, sub { 168 aio_read $fh, 7, 15, $buffer, 0, sub {
165 $_[0] > 0 or die "read error: $!"; 169 $_[0] > 0 or die "read error: $!";
166 print "read $_[0] bytes: <$buffer>\n"; 170 print "read $_[0] bytes: <$buffer>\n";
167 }; 171 };
168 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
169=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)
170 239
171Tries 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
172reading 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
173file 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
228=item aio_unlink $pathname, $callback->($status) 297=item aio_unlink $pathname, $callback->($status)
229 298
230Asynchronously unlink (delete) a file and call the callback with the 299Asynchronously unlink (delete) a file and call the callback with the
231result code. 300result code.
232 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
233=item aio_rmdir $pathname, $callback->($status) 317=item aio_rmdir $pathname, $callback->($status)
234 318
235Asynchronously rmdir (delete) a directory and call the callback with the 319Asynchronously rmdir (delete) a directory and call the callback with the
236result code. 320result code.
237 321
238=item aio_readdir $pathname $callback->($entries) 322=item aio_readdir $pathname, $callback->($entries)
239 323
240Unlike 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
241directory (i.e. opendir + readdir + closedir). The entries will not be 325directory (i.e. opendir + readdir + closedir). The entries will not be
242sorted, and will B<NOT> include the C<.> and C<..> entries. 326sorted, and will B<NOT> include the C<.> and C<..> entries.
243 327
278 362
279Then entires will be sorted into likely directories (everything without a 363Then entires will be sorted into likely directories (everything without a
280non-initial dot) and likely non-directories (everything else). Then every 364non-initial dot) and likely non-directories (everything else). Then every
281entry + 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
282faster because filesystems might detect the type of the entry without 366faster because filesystems might detect the type of the entry without
283reading the inode data (e.g. ext2s filetype feature). If that succeeds, 367reading the inode data (e.g. ext2fs filetype feature). If that succeeds,
284it 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
285will be checked seperately). 369will be checked seperately).
286 370
287If 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
288entries is assumed to be non-directories. 372entries is assumed to be non-directories.
294 378
295 $maxreq = 8 if $maxreq <= 0; 379 $maxreq = 8 if $maxreq <= 0;
296 380
297 # stat once 381 # stat once
298 aio_stat $path, sub { 382 aio_stat $path, sub {
299 $cb->() if $_[0]; 383 return $cb->() if $_[0];
300 my $hash1 = join ":", (stat _)[0,1,3,7,9]; 384 my $hash1 = join ":", (stat _)[0,1,3,7,9];
301 385
302 # read the directory entries 386 # read the directory entries
303 aio_readdir $path, sub { 387 aio_readdir $path, sub {
304 my $entries = shift 388 my $entries = shift
315 $ndirs = -1; 399 $ndirs = -1;
316 } else { 400 } else {
317 # if nlink == 2, we are finished 401 # if nlink == 2, we are finished
318 # on non-posix-fs's, we rely on nlink < 2 402 # on non-posix-fs's, we rely on nlink < 2
319 $ndirs = (stat _)[3] - 2 403 $ndirs = (stat _)[3] - 2
320 or $cb->([], $entries); 404 or return $cb->([], $entries);
321 } 405 }
322 406
323 # sort into likely dirs and likely nondirs 407 # sort into likely dirs and likely nondirs
324 # dirs == files without ".", short entries first 408 # dirs == files without ".", short entries first
325 $entries = [map $_->[0], 409 $entries = [map $_->[0],
341 } 425 }
342 } elsif (!$nreq) { 426 } elsif (!$nreq) {
343 # finished 427 # finished
344 undef $statcb; 428 undef $statcb;
345 undef $schedcb; 429 undef $schedcb;
346 $cb->(\@dirs, \@nondirs); 430 $cb->(\@dirs, \@nondirs) if $cb;
347 undef $cb; 431 undef $cb;
348 } 432 }
349 }; 433 };
350 $statcb = sub { 434 $statcb = sub {
351 my ($status, $entry) = @_; 435 my ($status, $entry) = @_;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines