File Coverage

blib/lib/IPC/Lock.pm
Criterion Covered Total %
statement 9 51 17.6
branch 0 16 0.0
condition 0 16 0.0
subroutine 3 10 30.0
pod 0 6 0.0
total 12 99 12.1


line stmt bran cond sub pod time code
1             package IPC::Lock;
2              
3 2     2   33180 use strict;
  2         4  
  2         87  
4 2     2   11 use warnings;
  2         5  
  2         495  
5              
6 2     2   3060 use Time::HiRes qw(gettimeofday);
  2         5697  
  2         11  
7              
8             our $VERSION = '0.20';
9             our @CATCH_SIGS = qw(TERM INT);
10              
11             ### from File::NFSLock
12             my $graceful_sig = sub {
13             print STDERR "Received SIG$_[0]\n" if @_;
14             # Perl's exit should safely DESTROY any objects
15             # still "alive" before calling the real _exit().
16             exit;
17             };
18              
19             sub new {
20 0     0 0   my $type = shift;
21 0 0         my @PASSED_ARGS = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
  0            
22 0           my @DEFAULT_ARGS = (
23             locked => {},
24             ttl => 60,
25             patience => 2,
26             increment => '0.05',
27             );
28              
29 0           my %ARGS = (@DEFAULT_ARGS, @PASSED_ARGS);
30 0 0         unless($ARGS{hostname}) {
31 0           require Sys::Hostname;
32 0           $ARGS{hostname} = &Sys::Hostname::hostname();
33             }
34              
35 0           foreach my $signal (@CATCH_SIGS) {
36 0 0 0       if (!$SIG{$signal} || $SIG{$signal} eq "DEFAULT") {
37 0           $SIG{$signal} = $graceful_sig;
38             }
39             }
40 0           return bless \%ARGS, $type;
41             }
42              
43             sub lock {
44 0     0 0   my $self = shift;
45 0   0       my $key = shift || die "need a key";
46 0           $self->{key} = $key;
47              
48 0           my $ttl = shift;
49 0 0 0       $ttl = $self->{ttl} unless( (defined $ttl) && length $ttl);
50              
51 0           my $patience = $self->{patience};
52 0           my $increment = $self->{increment};
53              
54 0           my $start = gettimeofday;
55              
56 0           my $got_lock = 0;
57              
58 0           while(1) {
59 0 0         if($self->atomic($key, $ttl)) {
60 0           $self->{locked}{$key} = 1;
61 0           $got_lock = 1;
62 0           last;
63             }
64 0 0         last if(gettimeofday - $start > $patience);
65 0           select(undef, undef, undef, $increment);
66             }
67              
68 0           return $got_lock;
69             }
70              
71             sub unlock {
72 0     0 0   my $self = shift;
73 0   0       my $key = shift || $self->{key} || die "need a key";
74 0           my $unlock = $self->unatomic($key);
75 0 0         if($unlock) {
76 0           delete $self->{locked}{$key};
77             }
78 0           return $unlock;
79             }
80              
81             sub DESTROY {
82 0     0     my $self = shift;
83              
84 0 0 0       if($self->{locked} && $self->{key} && $self->{locked}{$self->{key}}) {
      0        
85 0           $self->unlock($self->{key});
86             }
87             }
88              
89             sub atomic_value {
90 0     0 0   my $self = shift;
91 0           return "$self->{hostname}:$$:" . scalar gettimeofday;
92             }
93              
94             sub atomic {
95 0     0 0   die "please write your own atomic method";
96             }
97              
98             sub unatomic {
99 0     0 0   die "please write your own unatomic method";
100             }
101              
102             1;
103              
104             __END__