Move cp(1)-like permission changes from copy to cp,
[p5sagit/p5-mst-13.2.git] / lib / Thread / Semaphore.pm
CommitLineData
d21067e0 1package Thread::Semaphore;
3d1f1caf 2
89847188 3use strict;
4use warnings;
5
1090e072 6our $VERSION = '2.09';
89847188 7
83272a45 8use threads::shared;
89847188 9use Scalar::Util 1.10 qw(looks_like_number);
9c6f8578 10
89847188 11# Create a new semaphore optionally with specified count (count defaults to 1)
12sub new {
13 my $class = shift;
14 my $val :shared = @_ ? shift : 1;
3182b11b 15 if (!defined($val) ||
16 ! looks_like_number($val) ||
17 (int($val) != $val))
18 {
89847188 19 require Carp;
20 $val = 'undef' if (! defined($val));
21 Carp::croak("Semaphore initializer is not an integer: $val");
22 }
23 return bless(\$val, $class);
24}
25
26# Decrement a semaphore's count (decrement amount defaults to 1)
27sub down {
28 my $sema = shift;
29 lock($$sema);
30 my $dec = @_ ? shift : 1;
3182b11b 31 if (! defined($dec) ||
32 ! looks_like_number($dec) ||
33 (int($dec) != $dec) ||
34 ($dec < 1))
35 {
89847188 36 require Carp;
37 $dec = 'undef' if (! defined($dec));
38 Carp::croak("Semaphore decrement is not a positive integer: $dec");
39 }
40 cond_wait($$sema) until ($$sema >= $dec);
41 $$sema -= $dec;
42}
43
44# Increment a semaphore's count (increment amount defaults to 1)
45sub up {
46 my $sema = shift;
47 lock($$sema);
48 my $inc = @_ ? shift : 1;
3182b11b 49 if (! defined($inc) ||
50 ! looks_like_number($inc) ||
51 (int($inc) != $inc) ||
52 ($inc < 1))
53 {
89847188 54 require Carp;
55 $inc = 'undef' if (! defined($inc));
56 Carp::croak("Semaphore increment is not a positive integer: $inc");
57 }
58 ($$sema += $inc) > 0 and cond_broadcast($$sema);
59}
60
611;
9c6f8578 62
d516a115 63=head1 NAME
64
89847188 65Thread::Semaphore - Thread-safe semaphores
66
67=head1 VERSION
68
1090e072 69This document describes Thread::Semaphore version 2.09
d516a115 70
71=head1 SYNOPSIS
72
73 use Thread::Semaphore;
89847188 74 my $s = Thread::Semaphore->new();
75 $s->down(); # Also known as the semaphore P operation.
d516a115 76 # The guarded section is here
89847188 77 $s->up(); # Also known as the semaphore V operation.
d516a115 78
89847188 79 # The default semaphore value is 1
80 my $s = Thread::Semaphore-new($initial_value);
14180c03 81 $s->down($down_value);
d516a115 82 $s->up($up_value);
d516a115 83
5d582a37 84=head1 DESCRIPTION
85
89847188 86Semaphores provide a mechanism to regulate access to resources. Unlike
87locks, semaphores aren't tied to particular scalars, and so may be used to
5d582a37 88control access to anything you care to use them for.
89
89847188 90Semaphores don't limit their values to zero and one, so they can be used to
91control access to some resource that there may be more than one of (e.g.,
92filehandles). Increment and decrement amounts aren't fixed at one either,
93so threads can reserve or return multiple resources at once.
5d582a37 94
89847188 95=head1 METHODS
5d582a37 96
97=over 8
98
89847188 99=item ->new()
100
101=item ->new(NUMBER)
5d582a37 102
89847188 103C<new> creates a new semaphore, and initializes its count to the specified
104number (which must be an integer). If no number is specified, the
105semaphore's count defaults to 1.
5d582a37 106
89847188 107=item ->down()
5d582a37 108
89847188 109=item ->down(NUMBER)
5d582a37 110
89847188 111The C<down> method decreases the semaphore's count by the specified number
112(which must be an integer >= 1), or by one if no number is specified.
5d582a37 113
89847188 114If the semaphore's count would drop below zero, this method will block
115until such time as the semaphore's count is greater than or equal to the
116amount you're C<down>ing the semaphore's count by.
5d582a37 117
14180c03 118This is the semaphore "P operation" (the name derives from the Dutch
119word "pak", which means "capture" -- the semaphore operations were
120named by the late Dijkstra, who was Dutch).
121
89847188 122=item ->up()
5d582a37 123
89847188 124=item ->up(NUMBER)
5d582a37 125
89847188 126The C<up> method increases the semaphore's count by the number specified
127(which must be an integer >= 1), or by one if no number is specified.
128
129This will unblock any thread that is blocked trying to C<down> the
130semaphore if the C<up> raises the semaphore's count above the amount that
131the C<down> is trying to decrement it by. For example, if three threads
132are blocked trying to C<down> a semaphore by one, and another thread C<up>s
133the semaphore by two, then two of the blocked threads (which two is
134indeterminate) will become unblocked.
5d582a37 135
14180c03 136This is the semaphore "V operation" (the name derives from the Dutch
137word "vrij", which means "release").
138
5d582a37 139=back
140
0a7dbd1b 141=head1 NOTES
142
143Semaphores created by L<Thread::Semaphore> can be used in both threaded and
144non-threaded applications. This allows you to write modules and packages
145that potentially make use of semaphores, and that will function in either
146environment.
147
89847188 148=head1 SEE ALSO
d516a115 149
89847188 150Thread::Semaphore Discussion Forum on CPAN:
151L<http://www.cpanforum.com/dist/Thread-Semaphore>
d21067e0 152
89847188 153Annotated POD for Thread::Semaphore:
1090e072 154L<http://annocpan.org/~JDHEDDEN/Thread-Semaphore-2.09/lib/Thread/Semaphore.pm>
0a7dbd1b 155
156Source repository:
157L<http://code.google.com/p/thread-semaphore/>
d21067e0 158
89847188 159L<threads>, L<threads::shared>
d21067e0 160
89847188 161=head1 MAINTAINER
162
163Jerry D. Hedden, S<E<lt>jdhedden AT cpan DOT orgE<gt>>
164
165=head1 LICENSE
166
167This program is free software; you can redistribute it and/or modify it under
168the same terms as Perl itself.
169
170=cut