[ID 20020602.004] threads::shared::queue new nit
[p5sagit/p5-mst-13.2.git] / ext / threads / shared / queue.pm
1 package threads::shared::queue;
2
3 use threads::shared;
4 use strict;
5
6 our $VERSION = '1.00';
7
8 =head1 NAME
9
10 threads::shared::queue - thread-safe queues
11
12 =head1 SYNOPSIS
13
14     use threads::shared::queue;
15     my $q = new threads::shared::queue;
16     $q->enqueue("foo", "bar");
17     my $foo = $q->dequeue;    # The "bar" is still in the queue.
18     my $foo = $q->dequeue_nb; # returns "bar", or undef if the queue was
19                               # empty
20     my $left = $q->pending;   # returns the number of items still in the queue
21
22 =head1 DESCRIPTION
23
24 A queue, as implemented by C<threads::shared::queue> is a thread-safe 
25 data structure much like a list.  Any number of threads can safely 
26 add elements to the end of the list, or remove elements from the head 
27 of the list. (Queues don't permit adding or removing elements from 
28 the middle of the list).
29
30 =head1 FUNCTIONS AND METHODS
31
32 =over 8
33
34 =item new
35
36 The C<new> function creates a new empty queue.
37
38 =item enqueue LIST
39
40 The C<enqueue> method adds a list of scalars on to the end of the queue.
41 The queue will grow as needed to accommodate the list.
42
43 =item dequeue
44
45 The C<dequeue> method removes a scalar from the head of the queue and
46 returns it. If the queue is currently empty, C<dequeue> will block the
47 thread until another thread C<enqueue>s a scalar.
48
49 =item dequeue_nb
50
51 The C<dequeue_nb> method, like the C<dequeue> method, removes a scalar from
52 the head of the queue and returns it. Unlike C<dequeue>, though,
53 C<dequeue_nb> won't block if the queue is empty, instead returning
54 C<undef>.
55
56 =item pending
57
58 The C<pending> method returns the number of items still in the queue.
59
60 =back
61
62 =head1 SEE ALSO
63
64 L<threads>, L<threads::shared>
65
66 =cut
67
68 sub new {
69     my $class = shift;
70     my @q : shared = @_;
71     return bless \@q, $class;
72 }
73
74 sub dequeue  {
75     my $q = shift;
76     lock(@$q);
77     until(@$q) {
78         cond_wait(@$q);
79     }
80     return shift @$q;
81 }
82
83 sub dequeue_nb {
84   my $q = shift;
85   lock(@$q);
86   if (@$q) {
87     return shift @$q;
88   } else {
89     return undef;
90   }
91 }
92
93 sub enqueue {
94     my $q = shift;
95     lock(@$q);
96     push(@$q, @_) and cond_broadcast @$q;
97 }
98
99 sub pending  {
100   my $q = shift;
101   lock(@$q);
102   return scalar(@$q);
103 }
104
105 1;
106
107