ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/Signal.pm
Revision: 1.61
Committed: Sun Sep 21 01:23:26 2008 UTC (15 years, 8 months ago) by root
Branch: MAIN
CVS Tags: rel-4_746
Changes since 1.60: +1 -1 lines
Log Message:
4.746

File Contents

# Content
1 =head1 NAME
2
3 Coro::Signal - coroutine signals (binary semaphores)
4
5 =head1 SYNOPSIS
6
7 use Coro::Signal;
8
9 $sig = new Coro::Signal;
10
11 $sig->wait; # wait for signal
12
13 # ... some other "thread"
14
15 $sig->send;
16
17 =head1 DESCRIPTION
18
19 This module implements signal/binary semaphores/condition variables
20 (basically all the same thing). You can wait for a signal to occur or send
21 it, in which case it will wake up one waiter, or it can be broadcast,
22 waking up all waiters.
23
24 =over 4
25
26 =cut
27
28 package Coro::Signal;
29
30 BEGIN { eval { require warnings } && warnings->unimport ("uninitialized") }
31
32 use Coro ();
33
34 $VERSION = 4.746;
35
36 =item $s = new Coro::Signal;
37
38 Create a new signal.
39
40 =cut
41
42 sub new {
43 # [flag, [pid's]]
44 bless [], $_[0];
45 }
46
47 =item $s->wait
48
49 Wait for the signal to occur. Returns immediately if the signal has been
50 sent before.
51
52 Signals are not reliable: this function might return spuriously without
53 the signal being sent. This means you must always test for the condition
54 you are waiting for.
55
56 (If this is a real problem for you the situation might be remedied in a
57 future version).
58
59 =item $status = $s->timed_wait ($timeout)
60
61 Like C<wait>, but returns false if no signal happens within $timeout
62 seconds, otherwise true.
63
64 See C<wait> for some reliability concerns.
65
66 =cut
67
68 sub wait {
69 unless (delete $_[0][0]) {
70 push @{$_[0][1]}, $Coro::current;
71 &Coro::schedule;
72 }
73 }
74
75 sub timed_wait {
76 require Coro::Timer;
77 my $timeout = Coro::Timer::timeout($_[1]);
78
79 unless (delete $_[0][0]) {
80 push @{$_[0][1]}, $Coro::current;
81 &Coro::schedule;
82
83 return 0 if $timeout;
84 }
85
86 1
87 }
88
89 =item $s->send
90
91 Send the signal, waking up I<one> waiting process or remember the signal
92 if no process is waiting.
93
94 =cut
95
96 sub send {
97 $_[0][0] = 1;
98 (shift @{$_[0][1]})->ready if @{$_[0][1]};
99 }
100
101 =item $s->broadcast
102
103 Send the signal, waking up I<all> waiting process. If no process is
104 waiting the signal is lost.
105
106 =cut
107
108 sub broadcast {
109 if (my $waiters = delete $_[0][1]) {
110 $_->ready for @$waiters;
111 }
112 }
113
114 =item $s->awaited
115
116 Return true when the signal is being awaited by some process.
117
118 =cut
119
120 sub awaited {
121 ! ! @{$_[0][1]}
122 }
123
124 1;
125
126 =back
127
128 =head1 BUGS
129
130 This implementation is not currently very robust when the process is woken
131 up by other sources, i.e. C<wait> might return early.
132
133 =head1 AUTHOR
134
135 Marc Lehmann <schmorp@schmorp.de>
136 http://home.schmorp.de/
137
138 =cut
139