Fuse-Filesys-Virtual
view release on metacpan or search on metacpan
lib/Fuse/Filesys/Virtual/HandleCache.pm view on Meta::CPAN
#
# Fuse::Filesys::Virtual::HandleCache
#
#
package Fuse::Filesys::Virtual::HandleCache;
use warnings;
use strict;
=head1 NAME
Fuse::Filesys::Virtual::HandleCache - R/W handle cache manager
=head1 VERSION
Version 0.02
=cut
our $VERSION = '0.02';
=head1 SYNOPSIS
In Fuse::Filesys::Virtual, read and write handle is cached for
performance reason.
=head1 EXPORT
Nothing.
=cut
use POSIX qw(:errno_h :fcntl_h);
=head1 FUNCTIONS
=head2 new
constractor
=cut
sub new {
my $class = shift;
my ($filesys) = shift;
bless {
_filesys => $filesys,
_read => {},
_write => {},
}, $class;
}
=head2 is_busy
returns file or directory is used or not.
=cut
sub is_busy {
my $self = shift;
my ($fname) = @_;
return 1 if ($self->{_read}->{$fname});
return 1 if ($self->{_write}->{$fname});
# directory is busy?
for (keys %{$self->{_read}}, keys %{$self->{_write}}) {
return 1 if (/^\Q$fname\E\//);
}
return undef;
}
sub _file_exist {
my $self = shift;
my ($fname) = @_;
# by stat
my $ret;
eval {
$ret = $self->{_filesys}->stat($fname);
};
return $ret unless ($@ =~ /Unimplemented/);
eval {
$ret = $self->{_filesys}->test('f', $fname);
};
return $ret unless ($@ =~ /Unimplemented/);
die "cannot determine file status";
}
sub _read_open {
my $self = shift;
my ($fname) = @_;
# already opened?
return $self->{_read}->{$fname} if ($self->{_read}->{$fname});
my $fh = $self->{_filesys}->open_read($fname);
unless ($fh) {
my $eno = $! + 0;
if ($self->_file_exist($fname)) {
$! = $eno || EPERM;
die "cannot open file for reading: $!";
}
else {
$! = ENOENT;
die "file not found";
}
}
return $self->{_read}->{$fname} = { fh => $fh, pos => 0 };
}
sub _read_seek {
my $self = shift;
my ($fname, $offset) = @_;
my $c = $self->_read_open($fname);
return $c if ($c->{pos} == $offset);
my $ret = eval {
if ($self->{_filesys}->seek($c->{fh}, $offset, 0)) {
$c->{pos} = $offset;
( run in 1.403 second using v1.01-cache-2.11-cpan-39bf76dae61 )