summaryrefslogtreecommitdiff
path: root/ext/Thread
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2002-07-12 23:44:17 +0000
committerJarkko Hietaniemi <jhi@iki.fi>2002-07-12 23:44:17 +0000
commit83272a45226e83bd136d713158e9b44ace2dbc8d (patch)
treeee348b24fc5020ccd9e375cef8a5eb8e2bcd3d77 /ext/Thread
parent484fdf61e8653b10160ba1e8011888f52ab6825a (diff)
downloadperl-83272a45226e83bd136d713158e9b44ace2dbc8d.tar.gz
threads::shared::queue and semaphore become Thread::Semaphore
and Queue. The 5005threads case where the old Semaphore and Queue.pm (they are disguised as .pmx) should get magically installed instead has not been tested. p4raw-id: //depot/perl@17509
Diffstat (limited to 'ext/Thread')
-rw-r--r--ext/Thread/Queue.pmx104
-rw-r--r--ext/Thread/Semaphore.pmx94
2 files changed, 198 insertions, 0 deletions
diff --git a/ext/Thread/Queue.pmx b/ext/Thread/Queue.pmx
new file mode 100644
index 0000000000..481261043f
--- /dev/null
+++ b/ext/Thread/Queue.pmx
@@ -0,0 +1,104 @@
+package Thread::Queue;
+use Thread qw(cond_wait cond_broadcast);
+
+=head1 NAME
+
+Thread::Queue - thread-safe queues (5.005-threads)
+
+=head1 CAVEAT
+
+This Perl installation is using the old unsupported "5.005 threads".
+Use of the old threads model is discouraged.
+
+For the whole story about the development of threads in Perl, and why
+you should B<not> be using "old threads" unless you know what you're
+doing, see the CAVEAT of the C<Thread> module.
+
+=head1 SYNOPSIS
+
+ use Thread::Queue;
+ my $q = new Thread::Queue;
+ $q->enqueue("foo", "bar");
+ my $foo = $q->dequeue; # The "bar" is still in the queue.
+ my $foo = $q->dequeue_nb; # returns "bar", or undef if the queue was
+ # empty
+ my $left = $q->pending; # returns the number of items still in the queue
+
+=head1 DESCRIPTION
+
+A queue, as implemented by C<Thread::Queue> is a thread-safe data structure
+much like a list. Any number of threads can safely add elements to the end
+of the list, or remove elements from the head of the list. (Queues don't
+permit adding or removing elements from the middle of the list)
+
+=head1 FUNCTIONS AND METHODS
+
+=over 8
+
+=item new
+
+The C<new> function creates a new empty queue.
+
+=item enqueue LIST
+
+The C<enqueue> method adds a list of scalars on to the end of the queue.
+The queue will grow as needed to accomodate the list.
+
+=item dequeue
+
+The C<dequeue> method removes a scalar from the head of the queue and
+returns it. If the queue is currently empty, C<dequeue> will block the
+thread until another thread C<enqueue>s a scalar.
+
+=item dequeue_nb
+
+The C<dequeue_nb> method, like the C<dequeue> method, removes a scalar from
+the head of the queue and returns it. Unlike C<dequeue>, though,
+C<dequeue_nb> won't block if the queue is empty, instead returning
+C<undef>.
+
+=item pending
+
+The C<pending> method returns the number of items still in the queue. (If
+there can be multiple readers on the queue it's best to lock the queue
+before checking to make sure that it stays in a consistent state)
+
+=back
+
+=head1 SEE ALSO
+
+L<Thread>
+
+=cut
+
+sub new {
+ my $class = shift;
+ return bless [@_], $class;
+}
+
+sub dequeue : locked : method {
+ my $q = shift;
+ cond_wait $q until @$q;
+ return shift @$q;
+}
+
+sub dequeue_nb : locked : method {
+ my $q = shift;
+ if (@$q) {
+ return shift @$q;
+ } else {
+ return undef;
+ }
+}
+
+sub enqueue : locked : method {
+ my $q = shift;
+ push(@$q, @_) and cond_broadcast $q;
+}
+
+sub pending : locked : method {
+ my $q = shift;
+ return scalar(@$q);
+}
+
+1;
diff --git a/ext/Thread/Semaphore.pmx b/ext/Thread/Semaphore.pmx
new file mode 100644
index 0000000000..8d69ac540a
--- /dev/null
+++ b/ext/Thread/Semaphore.pmx
@@ -0,0 +1,94 @@
+package Thread::Semaphore;
+use Thread qw(cond_wait cond_broadcast);
+
+=head1 NAME
+
+Thread::Semaphore - thread-safe semaphores (5.005-threads)
+
+=head1 CAVEAT
+
+This Perl installation is using the old unsupported "5.005 threads".
+Use of the old threads model is discouraged.
+
+For the whole story about the development of threads in Perl, and why
+you should B<not> be using "old threads" unless you know what you're
+doing, see the CAVEAT of the C<Thread> module.
+
+=head1 SYNOPSIS
+
+ use Thread::Semaphore;
+ my $s = new Thread::Semaphore;
+ $s->up; # Also known as the semaphore V -operation.
+ # The guarded section is here
+ $s->down; # Also known as the semaphore P -operation.
+
+ # The default semaphore value is 1.
+ my $s = new Thread::Semaphore($initial_value);
+ $s->up($up_value);
+ $s->down($up_value);
+
+=head1 DESCRIPTION
+
+Semaphores provide a mechanism to regulate access to resources. Semaphores,
+unlike locks, aren't tied to particular scalars, and so may be used to
+control access to anything you care to use them for.
+
+Semaphores don't limit their values to zero or one, so they can be used to
+control access to some resource that may have more than one of. (For
+example, filehandles) Increment and decrement amounts aren't fixed at one
+either, so threads can reserve or return multiple resources at once.
+
+=head1 FUNCTIONS AND METHODS
+
+=over 8
+
+=item new
+
+=item new NUMBER
+
+C<new> creates a new semaphore, and initializes its count to the passed
+number. If no number is passed, the semaphore's count is set to one.
+
+=item down
+
+=item down NUMBER
+
+The C<down> method decreases the semaphore's count by the specified number,
+or one if no number has been specified. If the semaphore's count would drop
+below zero, this method will block until such time that the semaphore's
+count is equal to or larger than the amount you're C<down>ing the
+semaphore's count by.
+
+=item up
+
+=item up NUMBER
+
+The C<up> method increases the semaphore's count by the number specified,
+or one if no number's been specified. This will unblock any thread blocked
+trying to C<down> the semaphore if the C<up> raises the semaphore count
+above what the C<down>s are trying to decrement it by.
+
+=back
+
+=cut
+
+sub new {
+ my $class = shift;
+ my $val = @_ ? shift : 1;
+ bless \$val, $class;
+}
+
+sub down : locked : method {
+ my $s = shift;
+ my $inc = @_ ? shift : 1;
+ cond_wait $s until $$s >= $inc;
+ $$s -= $inc;
+}
+
+sub up : locked : method {
+ my $s = shift;
+ my $inc = @_ ? shift : 1;
+ ($$s += $inc) > 0 and cond_broadcast $s;
+}
+
+1;