1 |
package SWE::DB::Lock; |
2 |
use strict; |
3 |
use warnings; |
4 |
|
5 |
my $CurrentlyLocking = {}; |
6 |
my $LockTypes = [qw/ |
7 |
ID Name Index IDs Names Graph Weight Global |
8 |
/]; |
9 |
# If you are locking for Graph, then you cannot lock for Global, but |
10 |
# still you can lock for ID. |
11 |
|
12 |
use Fcntl ':flock'; |
13 |
|
14 |
sub new ($) { |
15 |
my $self = bless { |
16 |
'file_name' => 'lock', |
17 |
lock_type => 'Global', |
18 |
}, shift; |
19 |
return $self; |
20 |
} # new |
21 |
|
22 |
sub lock_type ($;$) { |
23 |
my $self = shift; |
24 |
if (@_) { |
25 |
$self->{lock_type} = shift; |
26 |
} |
27 |
return $self->{lock_type}; |
28 |
} # lock_type |
29 |
|
30 |
sub check_lockability ($) { |
31 |
my $self = shift; |
32 |
|
33 |
my $self_lt = $self->lock_type; |
34 |
for my $lt (@$LockTypes) { |
35 |
if ($self_lt eq $lt) { |
36 |
last; |
37 |
} elsif ($CurrentlyLocking->{$lt}) { |
38 |
die qq[$0: It is currently locking for "$lt" so that it cannot be locked for the "$self_lt"]; |
39 |
} |
40 |
} |
41 |
|
42 |
return 1; |
43 |
} # check_lockability |
44 |
|
45 |
sub lock ($) { |
46 |
my $self = shift; |
47 |
|
48 |
$self->check_lockability; |
49 |
$CurrentlyLocking->{$self->lock_type}++; |
50 |
warn "@{[$self->lock_type]} $CurrentlyLocking->{$self->lock_type} $self->{file_name}"; |
51 |
|
52 |
open my $file, '>', $self->{file_name} or die "$0: $self->{file_name}: $!"; |
53 |
flock $file, LOCK_EX; |
54 |
$self->{lock} = $file; |
55 |
} # lock |
56 |
|
57 |
sub unlock ($) { |
58 |
my $self = shift; |
59 |
|
60 |
$CurrentlyLocking->{$self->lock_type}--; |
61 |
|
62 |
close $self->{lock}; |
63 |
} # unlock |
64 |
|
65 |
sub DESTROY ($) { |
66 |
$_[0]->unlock; |
67 |
} # DESTROY |
68 |
|
69 |
1; |