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.116 by root, Wed Oct 3 21:27:51 2007 UTC vs.
Revision 1.117 by root, Sat Oct 6 14:05:19 2007 UTC

183 183
184=cut 184=cut
185 185
186package IO::AIO; 186package IO::AIO;
187 187
188use Carp ();
189
188no warnings; 190no warnings;
189use strict 'vars'; 191use strict 'vars';
190 192
191use base 'Exporter'; 193use base 'Exporter';
192 194
193BEGIN { 195BEGIN {
194 our $VERSION = '2.5'; 196 our $VERSION = '2.51';
195 197
196 our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat 198 our @AIO_REQ = qw(aio_sendfile aio_read aio_write aio_open aio_close aio_stat
197 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink 199 aio_lstat aio_unlink aio_rmdir aio_readdir aio_scandir aio_symlink
198 aio_readlink aio_fsync aio_fdatasync aio_readahead aio_rename aio_link 200 aio_readlink aio_fsync aio_fdatasync aio_readahead aio_rename aio_link
199 aio_move aio_copy aio_group aio_nop aio_mknod aio_load aio_rmtree aio_mkdir 201 aio_move aio_copy aio_group aio_nop aio_mknod aio_load aio_rmtree aio_mkdir
313=item aio_close $fh, $callback->($status) 315=item aio_close $fh, $callback->($status)
314 316
315Asynchronously close a file and call the callback with the result 317Asynchronously close a file and call the callback with the result
316code. 318code.
317 319
318Unlike the other functions operating on files, this function uses the 320Unfortunately, you can't do this to perl. Perl I<insists> very strongly on
319PerlIO layer to close the filehandle. The reason is that the PerlIO API 321closing the file descriptor associated with the filehandle itself. Here is
320insists on closing the underlying fd itself, no matter what, and doesn't 322what aio_close will try:
321allow modifications to the fd. Unfortunately, it is not clear that you can
322call PerlIO from different threads (actually, its quite clear that this
323won't work in some cases), so while it likely works perfectly with simple
324file handles (such as the ones created by C<aio_open>) it might fail in
325interesting ways for others.
326 323
327Having said that, aio_close tries to clean up the filehandle as much as 324 1. dup()licate the fd
328possible before handing it to an io thread, and generally does work. 325 2. asynchronously close() the duplicated fd
326 3. dup()licate the fd once more
327 4. let perl close() the filehandle
328 5. asynchronously close the duplicated fd
329
330The idea is that the first close() flushes stuff to disk that closing an
331fd will flush, so when perl closes the fd, nothing much will need to be
332flushed. The second async. close() will then flush stuff to disk that
333closing the last fd to the file will flush.
334
335Just FYI, SuSv3 has this to say on close:
336
337 All outstanding record locks owned by the process on the file
338 associated with the file descriptor shall be removed.
339
340 If fildes refers to a socket, close() shall cause the socket to be
341 destroyed. ... close() shall block for up to the current linger
342 interval until all data is transmitted.
343 [this actually sounds like a specification bug, but who knows]
344
345And at least Linux additionally actually flushes stuff on every close,
346even when the file itself is still open.
347
348Sounds enourmously inefficient and complicated? Yes... please show me how
349to nuke perl's fd out of existence...
350
351=cut
352
353sub aio_close($;$) {
354 aio_block {
355 my ($fh, $cb) = @_;
356
357 my $pri = aioreq_pri;
358 my $grp = aio_group $cb;
359
360 my $fd = fileno $fh;
361
362 defined $fd or Carp::croak "aio_close called with fd-less filehandle";
363
364 # if the dups fail we will simply get EBADF
365 my $fd2 = _dup $fd;
366 aioreq_pri $pri;
367 add $grp _aio_close $fd2, sub {
368 my $fd2 = _dup $fd;
369 close $fh;
370 aioreq_pri $pri;
371 add $grp _aio_close $fd2, sub {
372 $grp->result ($_[0]);
373 };
374 };
375
376 $grp
377 }
378}
329 379
330 380
331=item aio_read $fh,$offset,$length, $data,$dataoffset, $callback->($retval) 381=item aio_read $fh,$offset,$length, $data,$dataoffset, $callback->($retval)
332 382
333=item aio_write $fh,$offset,$length, $data,$dataoffset, $callback->($retval) 383=item aio_write $fh,$offset,$length, $data,$dataoffset, $callback->($retval)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines