File Coverage

blib/lib/Mail/Box/Locker/Multi.pm
Criterion Covered Total %
statement 48 61 78.6
branch 11 22 50.0
condition 1 3 33.3
subroutine 11 12 91.6
pod 4 5 80.0
total 75 103 72.8


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::Multi;{
13             our $VERSION = '4.01';
14             }
15              
16 2     2   2535 use parent 'Mail::Box::Locker';
  2         4  
  2         16  
17              
18 2     2   148 use strict;
  2         8  
  2         48  
19 2     2   10 use warnings;
  2         4  
  2         116  
20              
21 2     2   8 use Log::Report 'mail-box', import => [ qw/trace try/ ];
  2         4  
  2         13  
22              
23 2     2   420 use Scalar::Util qw/blessed/;
  2         4  
  2         1511  
24              
25             #--------------------
26              
27             sub init($)
28 1     1 0 20 { my ($self, $args) = @_;
29 1         11 $self->SUPER::init($args);
30              
31             my @use
32 1 50       10 = exists $args->{use} ? @{delete $args->{use}}
  0 50       0  
33             : $^O eq 'MSWin32' ? qw/Flock/
34             : qw/NFS FcntlLock Flock/;
35              
36 1         3 my (@lockers, @used);
37              
38 1         4 foreach my $method (@use)
39 3 50 33     13 { if(blessed $method && $method->isa('Mail::Box::Locker'))
40 0         0 { push @lockers, $method;
41 0         0 push @used, ref $method =~ s/.*\:\://r;
42 0         0 next;
43             }
44              
45 3     3   24 my $locker = try { Mail::Box::Locker->new(%$args, method => $method, timeout => 1) };
  3         1497  
46 3 100       597 defined $locker or next;
47              
48 2         5 push @lockers, $locker;
49 2         7 push @used, $method;
50             }
51              
52 1         21 $self->{MBLM_lockers} = \@lockers;
53 1         10 trace "Multi-locking via @used.";
54 1         98 $self;
55             }
56              
57             #--------------------
58              
59 2     2 1 4 sub lockers() { @{ $_[0]->{MBLM_lockers}} }
  2         10  
60              
61             sub name() {'MULTI'}
62              
63             sub _try_lock()
64 1     1   3 { my $self = shift;
65 1         2 my @successes;
66              
67 1         4 foreach my $locker ($self->lockers)
68             {
69 2 50       10 unless($locker->lock)
70 0         0 { $_->unlock for @successes;
71 0         0 return 0;
72             }
73 2         9 push @successes, $locker;
74             }
75              
76 1         7 1;
77             }
78              
79             #--------------------
80              
81             sub unlock()
82 1     1 1 3 { my $self = shift;
83 1 50       5 $self->hasLock or return $self;
84 1         4 $_->unlock for $self->lockers;
85 1         5 $self->SUPER::unlock;
86 1         3 $self;
87             }
88              
89             sub lock()
90 2     2 1 1608 { my $self = shift;
91 2 100       14 return 1 if $self->hasLock;
92              
93 1         8 my $timeout = $self->timeout;
94 1 50       6 my $end = $timeout eq 'NOTIMEOUT' ? -1 : $timeout;
95              
96 1         2 while(1)
97 1 50       4 { return $self->SUPER::lock
98             if $self->_try_lock;
99              
100 0 0         last unless --$end;
101 0           sleep 1;
102             }
103              
104 0           return 0;
105             }
106              
107             sub isLocked()
108 0     0 1   { my $self = shift;
109              
110             # Try get a lock
111 0 0         $self->_try_lock or return 0;
112              
113             # and release it immediately
114 0           $self->unlock;
115 0           1;
116             }
117              
118              
119             1;