package Perlbal::AIO; use POSIX qw(); sub aio_stat { my ($file, $cb) = @_; if ($Perlbal::AIO_MODE eq "linux") { Linux::AIO::aio_stat($file, $cb); } elsif ($Perlbal::AIO_MODE eq "ioaio") { IO::AIO::aio_stat($file, $cb); } else { stat($file); $cb->(); } } sub _fh_of_fd_mode { my ($fd, $mode) = @_; return undef unless defined $fd && $fd >= 0; #TODO: use the write MODE for the given $mode; my $fh = IO::Handle->new_from_fd($fd, 'r+'); my $num = fileno($fh); return $fh; } sub aio_open { my ($file, $flags, $mode, $cb) = @_; if ($Perlbal::AIO_MODE eq "linux") { Linux::AIO::aio_open($file, $flags, $mode, sub { my $fd = shift; my $fh = _fh_of_fd_mode($fd, $mode); $cb->($fh); }); } elsif ($Perlbal::AIO_MODE eq "ioaio") { IO::AIO::aio_open($file, $flags, $mode, $cb); } else { my $fh; my $rv = sysopen($fh, $file, $flags, $mode); $cb->($rv ? $fh : undef); } } sub aio_unlink { my ($file, $cb) = @_; if ($Perlbal::AIO_MODE eq "linux") { Linux::AIO::aio_unlink($file, $cb); } elsif ($Perlbal::AIO_MODE eq "ioaio") { IO::AIO::aio_unlink($file, $cb); } else { my $rv = unlink($file); $rv = $rv ? 0 : -1; $cb->($rv); } } sub aio_write { # 0 1 2 3(data) 4 my ($fh, $offset, $length, undef, $cb) = @_; return no_fh($cb) unless $fh; if ($Perlbal::AIO_MODE eq "linux") { Linux::AIO::aio_write($fh, $offset, $length, $_[3], 0, $cb); } elsif ($Perlbal::AIO_MODE eq "ioaio") { IO::AIO::aio_write($fh, $offset, $length, $_[3], 0, $cb); } else { my $rv = syswrite($fh, $_[3], $length, $offset); $cb->($rv); } } sub aio_read { # 0 1 2 3(data) 4 my ($fh, $offset, $length, undef, $cb) = @_; return no_fh($cb) unless $fh; if ($Perlbal::AIO_MODE eq "linux") { Linux::AIO::aio_read($fh, $offset, $length, $_[3], 0, $cb); } elsif ($Perlbal::AIO_MODE eq "ioaio") { IO::AIO::aio_read($fh, $offset, $length, $_[3], 0, $cb); } else { my $rv = sysread($fh, $_[3], $length, $offset); $cb->($rv); } } sub no_fh { my $cb = shift; my $i = 1; my $stack_trace = ""; while (my ($pkg, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask) = caller($i++)) { $stack_trace .= " at $filename:$line $subroutine\n"; } Perlbal::log("crit", "Undef \$fh: $stack_trace"); $cb->(undef); return undef; } 1;