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