ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.48
Committed: Wed Jan 24 16:24:21 2007 UTC (17 years, 5 months ago) by root
Branch: MAIN
CVS Tags: rel-4_0, rel-3_55, rel-3_51, rel-4_01, rel-4_03, rel-4_02, rel-3_6, rel-3_62, rel-3_63, rel-3_61, rel-3_5, rel-3_501
Changes since 1.47: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Coro::Event - do events the coro-way
4
5 =head1 SYNOPSIS
6
7 use Coro;
8 use Coro::Event;
9
10 sub keyboard : Coro {
11 my $w = Coro::Event->io(fd => \*STDIN, poll => 'r');
12 while() {
13 print "cmd> ";
14 my $ev = $w->next; my $cmd = <STDIN>;
15 unloop unless $cmd ne "";
16 print "data> ";
17 my $ev = $w->next; my $data = <STDIN>;
18 }
19 }
20
21 loop;
22
23 # wait for input on stdin for one second
24
25 Coro::Event::do_io (fd => \*STDIN, timeout => 1) & Event::Watcher::R
26 or die "no input received";
27
28 =head1 DESCRIPTION
29
30 This module enables you to create programs using the powerful Event model
31 (and module), while retaining the linear style known from simple or
32 threaded programs.
33
34 This module provides a method and a function for every watcher type
35 (I<flavour>) (see L<Event>). The only difference between these and the
36 watcher constructors from Event is that you do not specify a callback
37 function - it will be managed by this module.
38
39 Your application should just create all necessary coroutines and then call
40 Coro::Event::loop.
41
42 Please note that even programs or modules (such as
43 L<Coro::Handle|Coro::Handle>) that use "traditional"
44 event-based/continuation style will run more efficient with this module
45 then when using only Event.
46
47 =head1 WARNING
48
49 Please note that Event does not support coroutines or threads. That
50 means that you B<MUST NOT> block in an event callback. Again: In Event
51 callbacks, you I<must never ever> call a Coroutine fucntion that blocks
52 the current coroutine.
53
54 While this seems to work superficially, it will eventually cause memory
55 corruption.
56
57 =head1 SEMANTICS
58
59 Whenever Event blocks (e.g. in a call to C<one_event>, C<loop> etc.),
60 this module cede's to all other coroutines with the same or higher
61 priority. When any coroutines of lower priority are ready, it will not
62 block but run one of them and then check for events.
63
64 The effect is that coroutines with the same or higher priority than
65 the blocking coroutine will keep Event from checking for events, while
66 coroutines with lower priority are being run, but Event checks for new
67 events after every cede.
68
69 =head1 FUNCTIONS
70
71 =over 4
72
73 =cut
74
75 package Coro::Event;
76
77 no warnings;
78
79 use Carp;
80 no warnings;
81
82 use Coro;
83 use Coro::Timer;
84 use Event qw(loop unloop); # we are re-exporting this, cooool!
85
86 use XSLoader;
87
88 use base Exporter::;
89
90 our @EXPORT = qw(loop unloop sweep);
91
92 BEGIN {
93 our $VERSION = '2.1';
94
95 local $^W = 0; # avoid redefine warning for Coro::ready;
96 XSLoader::load __PACKAGE__, $VERSION;
97 }
98
99 =item $w = Coro::Event->flavour (args...)
100
101 Create and return a watcher of the given type.
102
103 Examples:
104
105 my $reader = Coro::Event->io(fd => $filehandle, poll => 'r');
106 $reader->next;
107
108 =cut
109
110 =item $w->next
111
112 Wait for and return the next event of the event queue of the watcher. The
113 returned event objects support two methods only: C<hits> and C<got>, both
114 of which return integers: the number this watcher was hit for this event,
115 and the mask of poll events received.
116
117 =cut
118
119 =item do_flavour args...
120
121 Create a watcher of the given type and immediately call it's next method,
122 returning the event.
123
124 This is less efficient then calling the constructor once and the next
125 method often, but it does save typing sometimes.
126
127 =cut
128
129 for my $flavour (qw(idle var timer io signal)) {
130 push @EXPORT, "do_$flavour";
131 my $new = \&{"Event::$flavour"};
132 my $class = "Coro::Event::$flavour";
133 my $type = $flavour eq "io" ? 1 : 0;
134 @{"${class}::ISA"} = (Coro::Event::, "Event::$flavour");
135 my $coronew = sub {
136 # how does one do method-call-by-name?
137 # my $w = $class->SUPER::$flavour(@_);
138
139 shift eq Coro::Event::
140 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
141
142 my $w = $new->($class,
143 desc => $flavour,
144 @_,
145 parked => 1,
146 );
147
148 _install_std_cb $w, $type;
149
150 # reblessing due to Event being broken
151 bless $w, $class
152 };
153 *{ $flavour } = $coronew;
154 *{"do_$flavour"} = sub {
155 unshift @_, Coro::Event::;
156 @_ = &$coronew;
157 &Coro::schedule while &_next;
158 $_[0]->cancel;
159 &_event
160 };
161 }
162
163 # do schedule in perl to avoid forcing a stack allocation.
164 # this is about 10% slower, though.
165 sub next($) {
166 &Coro::schedule while &_next;
167
168 &_event
169 }
170
171 sub Coro::Event::Event::hits { $_[0][3] }
172 sub Coro::Event::Event::got { $_[0][4] }
173
174 =item sweep
175
176 Similar to Event::one_event and Event::sweep: The idle task is called once
177 (this has the effect of jumping back into the Event loop once to serve new
178 events).
179
180 The reason this function exists is that you sometimes want to serve events
181 while doing other work. Calling C<Coro::cede> does not work because
182 C<cede> implies that the current coroutine is runnable and does not call
183 into the Event dispatcher.
184
185 =cut
186
187 sub sweep {
188 Event::one_event 0; # for now
189 }
190
191 =item $result = loop([$timeout])
192
193 This is the version of C<loop> you should use instead of C<Event::loop>
194 when using this module - it will ensure correct scheduling in the presence
195 of events.
196
197 =item unloop([$result])
198
199 Same as Event::unloop (provided here for your convinience only).
200
201 =cut
202
203 $Coro::idle = \&Event::one_event; # inefficient
204
205 1;
206
207 =back
208
209 =head1 AUTHOR
210
211 Marc Lehmann <schmorp@schmorp.de>
212 http://home.schmorp.de/
213
214 =cut
215