File Coverage

blib/lib/App/Highlander.pm
Criterion Covered Total %
statement 25 38 65.7
branch 1 10 10.0
condition 4 11 36.3
subroutine 7 9 77.7
pod 2 2 100.0
total 39 70 55.7


line stmt bran cond sub pod time code
1             # ABSTRACT: Module that provides simple named locks
2             package App::Highlander;
3             $App::Highlander::VERSION = '0.001';
4 4     4   2355 use strict;
  4         7  
  4         96  
5 4     4   20 use warnings;
  4         6  
  4         112  
6              
7 4     4   3135 use English qw(-no_match_vars);
  4         14702  
  4         21  
8 4     4   1686 use Fcntl qw(:flock);
  4         6  
  4         397  
9 4     4   4714 use Path::Tiny;
  4         48525  
  4         1803  
10              
11             our $LOCKDIR = '/var/highlander/';
12             our $LOCKFILE;
13              
14             sub get_lock {
15 3     3 1 25 my ($lock_string) = @_;
16 3         13 $lock_string = _build_lock_string($lock_string);
17            
18 3 50       822 open $LOCKFILE, '>>', $lock_string
19             or die "Unable to create LOCKFILE '$lock_string': $!";
20              
21 0         0 my $got_lock;
22 0 0       0 if ( $got_lock = flock($LOCKFILE, LOCK_EX|LOCK_NB) ) {
23 0         0 print {$LOCKFILE} $PID;
  0         0  
24             }
25            
26 0 0       0 return $got_lock ? $lock_string : 0;
27             }
28              
29             sub release_lock {
30 0     0 1 0 my ($lock_string) = @_;
31 0 0       0 return unless _have_lock($lock_string);
32              
33 0         0 $lock_string = _build_lock_string($lock_string);
34 0 0 0     0 return close($LOCKFILE) && unlink($lock_string)
35             ? $lock_string
36             : 0;
37             }
38              
39             sub _have_lock {
40 0     0   0 my ($lock_string) = @_;
41 0         0 $lock_string = _build_lock_string($lock_string);
42              
43 0         0 my $PID_PATTERN = qr/^$PID/;
44 0   0     0 return -e $lock_string && `cat $lock_string` =~ m/$PID_PATTERN/;
45             }
46              
47             sub _build_lock_string {
48 3     3   8 my ($lock_string) = @_;
49 3   100     15 $lock_string //= '';
50            
51 3         9 my ($normalized_programname) = $PROGRAM_NAME;
52 3         20 $normalized_programname =~ s|^.*/||;
53 3         17 $normalized_programname =~ s|\..*$||;
54            
55 3   66     25 my $lock_name = join ':',
56             ($lock_string || ()),"${normalized_programname}.lock";
57 3         17 return path($LOCKDIR, $lock_name)->canonpath;
58             }
59              
60             1;
61              
62             __END__