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