line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package IPC::Semaphore::Set; |
2
|
4
|
|
|
4
|
|
67378
|
use strict; |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
120
|
|
3
|
4
|
|
|
4
|
|
14
|
use warnings; |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
94
|
|
4
|
|
|
|
|
|
|
|
5
|
4
|
|
|
4
|
|
74
|
use 5.008; |
|
4
|
|
|
|
|
12
|
|
6
|
4
|
|
|
4
|
|
1984
|
use Digest::CRC qw(crc8); |
|
4
|
|
|
|
|
8249
|
|
|
4
|
|
|
|
|
347
|
|
7
|
4
|
|
|
4
|
|
1995
|
use IPC::SysV qw(IPC_PRIVATE IPC_CREAT IPC_NOWAIT S_IRUSR S_IWUSR); |
|
4
|
|
|
|
|
4054
|
|
|
4
|
|
|
|
|
711
|
|
8
|
4
|
|
|
4
|
|
2282
|
use IPC::Semaphore; |
|
4
|
|
|
|
|
17845
|
|
|
4
|
|
|
|
|
143
|
|
9
|
4
|
|
|
4
|
|
2078
|
use IPC::Semaphore::Set::Resource; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
2588
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our $VERSION = 1.20; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
############ |
14
|
|
|
|
|
|
|
## Public ## |
15
|
|
|
|
|
|
|
############ |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub new |
18
|
|
|
|
|
|
|
{ |
19
|
7
|
|
|
7
|
1
|
71
|
my $class = shift; |
20
|
7
|
50
|
|
|
|
45
|
my $args = ref($_[0]) ? $_[0] : {@_}; |
21
|
|
|
|
|
|
|
# set some sane defaults: we want at least one resource (semaphore in the set), |
22
|
|
|
|
|
|
|
# and for each semaphore we want it to have a value of at least one, and |
23
|
|
|
|
|
|
|
# when working on the semaphore by default we want to use IPC_CREAT to create |
24
|
|
|
|
|
|
|
# the semaphore if it didn't already exist, and S_IRUSR & S_IWUSR to give the |
25
|
|
|
|
|
|
|
# semaphore read and write permissions for the current perl user which you could |
26
|
|
|
|
|
|
|
# see by getting and viewing the results of the perl function getlogin() |
27
|
7
|
|
100
|
|
|
44
|
$args->{_resources} = delete($args->{resources}) || 1; |
28
|
7
|
|
100
|
|
|
34
|
$args->{_value} = delete($args->{value}) || 1; |
29
|
7
|
|
33
|
|
|
66
|
$args->{_flags} = delete($args->{flags}) || S_IRUSR | S_IWUSR | IPC_CREAT; |
30
|
|
|
|
|
|
|
# determine if we're using a key_name, key, or private semaphore set |
31
|
7
|
|
|
|
|
284
|
my $self = bless($args, $class); |
32
|
7
|
100
|
|
|
|
41
|
if (my $key = $self->{key}) { |
|
|
100
|
|
|
|
|
|
33
|
1
|
50
|
|
|
|
7
|
if ($key =~ m/[^0-9]/) { |
34
|
0
|
|
|
|
|
0
|
die "key [$key] was not numeric"; |
35
|
|
|
|
|
|
|
} |
36
|
1
|
|
|
|
|
7
|
$self->{_pre_exist} = semget($key, 0, IPC_NOWAIT); |
37
|
1
|
|
|
|
|
95
|
$self->{_key} = $key; |
38
|
1
|
|
|
|
|
11
|
$self->{_semaphore} = IPC::Semaphore->new($key, $self->{_resources}, $self->{_flags}); |
39
|
|
|
|
|
|
|
} elsif (my $key_name = $self->{key_name}) { |
40
|
5
|
|
|
|
|
11
|
$self->{_key_name} = $key_name; |
41
|
5
|
|
|
|
|
44
|
$self->{_key} = crc8($key_name); |
42
|
5
|
|
|
|
|
187
|
$self->{_pre_exist} = semget($self->{_key}, 0, IPC_NOWAIT); |
43
|
5
|
|
|
|
|
86
|
$self->{_semaphore} = IPC::Semaphore->new($self->key, $self->{_resources}, $self->{_flags}); |
44
|
|
|
|
|
|
|
} else { |
45
|
1
|
|
|
|
|
5
|
$self->{_semaphore} = IPC::Semaphore->new(IPC_PRIVATE, $self->{_resources}, $self->{_flags}); |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
# bail out if we didn't get an IPC::Semaphore |
48
|
7
|
50
|
|
|
|
158
|
if (ref($self->semaphore) ne 'IPC::Semaphore') { |
49
|
0
|
|
|
|
|
0
|
die 'could not get a semaphore with ' . $self->key . ": $!"; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
# if we created this semaphore, allow use of 'available' but if we didn't, don't clobber what |
52
|
|
|
|
|
|
|
# the semaphore resources were already set to |
53
|
7
|
100
|
|
|
|
22
|
if (!$self->{_pre_exist}) { |
54
|
5
|
|
|
|
|
11
|
$self->semaphore->setall(($self->{_value}) x $self->{_resources}); |
55
|
|
|
|
|
|
|
} |
56
|
7
|
|
|
|
|
192
|
return $self; |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub resource |
60
|
|
|
|
|
|
|
{ |
61
|
23
|
|
|
23
|
1
|
1006814
|
my $self = shift; |
62
|
23
|
50
|
|
|
|
80
|
my $args = ref($_[0]) ? $_[0] : {@_}; |
63
|
|
|
|
|
|
|
# default to 0, the first resource in the set |
64
|
23
|
100
|
|
|
|
72
|
$args->{number} = $args->{number} ? $args->{number} : 0; |
65
|
23
|
100
|
|
|
|
96
|
if (!$self->{resources}{$args->{number}}) { |
66
|
8
|
100
|
|
|
|
65
|
$args->{key} = $self->key ? $self->key : IPC_PRIVATE; |
67
|
8
|
|
|
|
|
20
|
$args->{semaphore} = $self->semaphore; |
68
|
8
|
|
|
|
|
48
|
$self->{resources}{$args->{number}} = IPC::Semaphore::Set::Resource->new($args); |
69
|
|
|
|
|
|
|
} |
70
|
23
|
|
|
|
|
109
|
return $self->{resources}{$args->{number}}; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub resources |
74
|
|
|
|
|
|
|
{ |
75
|
1
|
|
|
1
|
1
|
503
|
my $self = shift; |
76
|
1
|
|
|
|
|
4
|
my $total = () = $self->semaphore->getall; |
77
|
1
|
|
|
|
|
51
|
my @resources; |
78
|
1
|
|
|
|
|
5
|
for (0..($total - 1)) { |
79
|
3
|
|
|
|
|
8
|
push(@resources, $self->resource(number => $_)); |
80
|
|
|
|
|
|
|
} |
81
|
1
|
50
|
|
|
|
7
|
return wantarray ? @resources : \@resources; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
############ |
85
|
|
|
|
|
|
|
## Helper ## |
86
|
|
|
|
|
|
|
############ |
87
|
|
|
|
|
|
|
|
88
|
0
|
|
|
0
|
1
|
0
|
sub id {return shift->sem->id} |
89
|
21
|
|
|
21
|
1
|
77
|
sub key {return shift->{_key}} |
90
|
0
|
|
|
0
|
1
|
0
|
sub keyName {return shift->{_key_name}} |
91
|
4
|
50
|
|
4
|
1
|
967
|
sub remove {return shift->semaphore->remove ? 1 : 0} |
92
|
26
|
|
|
26
|
1
|
730
|
sub semaphore {return shift->{_semaphore}} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
1; |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
__END__ |