ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
Revision: 1.91
Committed: Sat Aug 22 22:36:23 2009 UTC (14 years, 9 months ago) by root
Branch: MAIN
CVS Tags: rel-5_17
Changes since 1.90: +1 -1 lines
Log Message:
5.17

File Contents

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