File Coverage

blib/lib/Mail/Box/Locker.pm
Criterion Covered Total %
statement 52 55 94.5
branch 15 24 62.5
condition 8 13 61.5
subroutine 16 19 84.2
pod 10 12 83.3
total 101 123 82.1


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;{
13             our $VERSION = '4.01';
14             }
15              
16 34     34   2882 use parent 'Mail::Reporter';
  34         83  
  34         223  
17              
18 34     34   2644 use strict;
  34         64  
  34         932  
19 34     34   763 use warnings;
  34         112  
  34         2450  
20              
21 34     34   207 use Log::Report 'mail-box', import => [ qw/__x error panic/ ];
  34         95  
  34         347  
22              
23 34     34   6475 use Scalar::Util qw/weaken/;
  34         98  
  34         2314  
24 34     34   201 use Devel::GlobalDestruction qw/in_global_destruction/;
  34         56  
  34         367  
25              
26             #--------------------
27              
28             my %lockers = (
29             DOTLOCK => __PACKAGE__ .'::DotLock',
30             FCNTLLOCK => __PACKAGE__ .'::FcntlLock',
31             FLOCK => __PACKAGE__ .'::Flock',
32             MULTI => __PACKAGE__ .'::Multi',
33             MUTT => __PACKAGE__ .'::Mutt',
34             NFS => __PACKAGE__ .'::NFS',
35             NONE => __PACKAGE__,
36             POSIX => __PACKAGE__ .'::POSIX',
37             );
38              
39             sub new(@)
40 92     92 1 1488421 { my ($class, %args) = @_;
41 92 50       407 $class eq __PACKAGE__ or return $class->SUPER::new(%args);
42              
43             # Try to figure out which locking method we really want (bootstrap)
44              
45             my $method
46             = ! defined $args{method} ? 'DOTLOCK'
47             : ref $args{method} eq 'ARRAY' ? 'MULTI'
48 92 50       2754 : uc $args{method};
    50          
49              
50 92 50 33     577 my $create = $lockers{$method} || $args{$method}
51             or error __x"no locking method {name} defined: use {avail}.", name => $method, avail => [ keys %lockers ];
52              
53             # compile the locking module (if needed)
54 92         10993 eval "require $create";
55 92 100       741 error __x"failed to use locking module {class}:\n{error}", class => $create, error => $@ if $@;
56              
57 91 50       481 $args{use} = $args{method} if ref $args{method} eq 'ARRAY';
58 91         816 $create->SUPER::new(%args);
59             }
60              
61             sub init($)
62 91     91 0 1082 { my ($self, $args) = @_;
63 91         557 $self->SUPER::init($args);
64              
65 91   50     811 $self->{MBL_expires} = $args->{expires} || 3600; # one hour
66 91   100     510 $self->{MBL_timeout} = $args->{timeout} || 10; # ten secs
67 91   66     529 $self->{MBL_filename} = $args->{file} || $args->{folder}->name;
68 91         283 $self->{MBL_has_lock} = 0;
69              
70 91         470 $self->folder($args->{folder});
71 91         841 $self;
72             }
73              
74             #--------------------
75              
76 7 50   7 1 20 sub timeout(;$) { my $self = shift; @_ ? $self->{MBL_timeout} = shift : $self->{MBL_timeout} }
  7         38  
77 3 50   3 1 7 sub expires(;$) { my $self = shift; @_ ? $self->{MBL_expires} = shift : $self->{MBL_expires} }
  3         20  
78              
79              
80 0     0 1 0 sub name { $_[0]->notImplemented }
81              
82 0     0 0 0 sub lockMethod($$$$) { panic "Method removed: use inheritance to implement own method." }
83              
84              
85             sub folder(;$)
86 98     98 1 283 { my $self = shift;
87 98 100 66     931 @_ && $_[0] or return $self->{MBL_folder};
88              
89 91         337 $self->{MBL_folder} = shift;
90 91         292 weaken $self->{MBL_folder};
91             }
92              
93              
94 144 100   144 1 2045 sub filename(;$) { my $self = shift; @_ ? $self->{MBL_filename} = shift : $self->{MBL_filename} }
  144         661  
95              
96             #--------------------
97              
98 84     84 1 520 sub lock($) { $_[0]->{MBL_has_lock} = 1 }
99              
100              
101 0     0 1 0 sub isLocked($) {0}
102              
103              
104 119     119 1 609 sub hasLock() { $_[0]->{MBL_has_lock} }
105              
106              
107             # implementation hazard: the unlock must be self-reliant, without
108             # help by the folder, because it may be called at global destruction
109             # after the folder has been removed.
110              
111 119     119 1 438 sub unlock() { $_[0]->{MBL_has_lock} = 0 }
112              
113             #--------------------
114              
115             sub DESTROY()
116 90     90   28400 { my $self = shift;
117 90 50       3706 return $self if in_global_destruction;
118              
119 90 50       923 $self->unlock if $self->hasLock;
120 90         621 $self->SUPER::DESTROY;
121 90         6443 $self;
122             }
123              
124             1;