IPC-Lock

 view release on metacpan or  search on metacpan

lib/IPC/Lock.pm  view on Meta::CPAN

package IPC::Lock;

use strict;
use warnings;

use Time::HiRes qw(gettimeofday);

our $VERSION    = '0.20';
our @CATCH_SIGS = qw(TERM INT);

### from File::NFSLock
my $graceful_sig = sub {
    print STDERR "Received SIG$_[0]\n" if @_;
  # Perl's exit should safely DESTROY any objects
  # still "alive" before calling the real _exit().
    exit;
};

sub new {
    my $type  = shift;
    my @PASSED_ARGS = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
    my @DEFAULT_ARGS = (
        locked    => {},
        ttl       => 60,
        patience  => 2,
        increment => '0.05',
    );

    my %ARGS = (@DEFAULT_ARGS, @PASSED_ARGS);
    unless($ARGS{hostname}) {
        require Sys::Hostname;
        $ARGS{hostname} = &Sys::Hostname::hostname();
    }

    foreach my $signal (@CATCH_SIGS) {
        if (!$SIG{$signal} || $SIG{$signal} eq "DEFAULT") {
            $SIG{$signal} = $graceful_sig;
        }
    }
    return bless \%ARGS, $type;
}

sub lock {
    my $self = shift;
    my $key = shift || die "need a key";
    $self->{key} = $key;

    my $ttl = shift;
    $ttl = $self->{ttl} unless( (defined $ttl) && length $ttl);

    my $patience = $self->{patience};
    my $increment = $self->{increment};

    my $start = gettimeofday;

    my $got_lock = 0;

    while(1) {
        if($self->atomic($key, $ttl)) {
            $self->{locked}{$key} = 1;
            $got_lock = 1;
            last;
        }
        last if(gettimeofday - $start > $patience);
        select(undef, undef, undef, $increment);
    }

    return $got_lock;
}

sub unlock {
    my $self = shift;
    my $key = shift || $self->{key} || die "need a key";
    my $unlock = $self->unatomic($key);
    if($unlock) {



( run in 1.411 second using v1.01-cache-2.11-cpan-39bf76dae61 )