File Coverage

blib/lib/Mail/Box/Locker/Flock.pm
Criterion Covered Total %
statement 38 50 76.0
branch 6 18 33.3
condition n/a
subroutine 10 11 90.9
pod 3 3 100.0
total 57 82 69.5


line stmt bran cond sub pod time code
1             # This code is part of Perl distribution Mail-Box version 4.01.
2             # The POD got stripped from this file by OODoc version 3.05.
3             # For contributors see file ChangeLog.
4              
5             # This software is copyright (c) 2001-2025 by Mark Overmeer.
6              
7             # This is free software; you can redistribute it and/or modify it under
8             # the same terms as the Perl 5 programming language system itself.
9             # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
10              
11              
12             package Mail::Box::Locker::Flock;{
13             our $VERSION = '4.01';
14             }
15              
16 3     3   2036 use parent 'Mail::Box::Locker';
  3         7  
  3         20  
17              
18 3     3   229 use strict;
  3         7  
  3         79  
19 3     3   14 use warnings;
  3         4  
  3         206  
20              
21 3     3   15 use Log::Report 'mail-box', import => [ qw/__x error fault warning/ ];
  3         6  
  3         20  
22              
23 3     3   542 use Fcntl qw/:DEFAULT :flock/;
  3         6  
  3         1218  
24 3     3   21 use Errno qw/EAGAIN/;
  3         6  
  3         2076  
25              
26             #--------------------
27              
28             sub name() {'FLOCK'}
29              
30             sub _try_lock($)
31 2     2   7 { my ($self, $file) = @_;
32 2         33 flock $file, LOCK_EX|LOCK_NB;
33             }
34              
35             sub _unlock($)
36 2     2   6 { my ($self, $file) = @_;
37 2         20 flock $file, LOCK_UN;
38 2         6 $self;
39             }
40              
41             #--------------------
42              
43             # 'r+' is require under Solaris and AIX, other OSes are satisfied with 'r'.
44             my $lockfile_access_mode = ($^O eq 'solaris' || $^O eq 'aix') ? '+<:raw' : '<:raw';
45              
46             sub lock()
47 3     3 1 2568 { my $self = shift;
48 3         15 my $folder = $self->folder;
49              
50 3 100       19 ! $self->hasLock
51             or warning(__x"folder {name} already flocked.", name => $folder), return 1;
52              
53 2         24 my $filename = $self->filename;
54 2 50       146 open my $fh, $lockfile_access_mode, $filename
55             or fault __x"unable to open flock file {file} for {folder}", file => $filename, folder => $folder;
56              
57 2         26 my $timeout = $self->timeout;
58 2 50       11 my $end = $timeout eq 'NOTIMEOUT' ? -1 : $timeout;
59              
60 2         4 while(1)
61 2 50       10 { if($self->_try_lock($fh))
62 2         8 { $self->{MBLF_filehandle} = $fh;
63 2         19 return $self->SUPER::lock;
64             }
65              
66 0 0       0 $! == EAGAIN
67             or fault __x"will never get a flock on {file} for {folder}", file => $filename, folder => $folder;
68              
69 0 0       0 --$end or last;
70 0         0 sleep 1;
71             }
72              
73 0         0 return 0;
74             }
75              
76              
77             sub isLocked()
78 0     0 1 0 { my $self = shift;
79 0         0 my $filename = $self->filename;
80              
81 0 0       0 open my($fh), $lockfile_access_mode, $filename
82             or fault __x"unable to check lock file {file} for {folder}", file => $filename, folder => $self->folder;
83              
84 0 0       0 $self->_try_lock($fh) or return 0;
85 0         0 $self->_unlock($fh);
86 0         0 $fh->close;
87              
88 0         0 $self->SUPER::unlock;
89 0         0 1;
90             }
91              
92             sub unlock()
93 2     2 1 898 { my $self = shift;
94              
95             $self->_unlock(delete $self->{MBLF_filehandle})
96 2 50       10 if $self->hasLock;
97              
98 2         120 $self->SUPER::unlock;
99 2         9 $self;
100             }
101              
102             1;