ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Event/Event.pm
(Generate patch)

Comparing Coro/Event/Event.pm (file contents):
Revision 1.30 by root, Tue Nov 29 12:36:18 2005 UTC vs.
Revision 1.54 by root, Fri Apr 25 04:28:50 2008 UTC

18 } 18 }
19 } 19 }
20 20
21 loop; 21 loop;
22 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 # use a separate coroutine for event processing, if impossible in main:
29 Coro::async { Event::loop };
30
23=head1 DESCRIPTION 31=head1 DESCRIPTION
24 32
25This module enables you to create programs using the powerful Event model 33This module enables you to create programs using the powerful Event model
26(and module), while retaining the linear style known from simple or 34(and module), while retaining the linear style known from simple or
27threaded programs. 35threaded programs.
32function - it will be managed by this module. 40function - it will be managed by this module.
33 41
34Your application should just create all necessary coroutines and then call 42Your application should just create all necessary coroutines and then call
35Coro::Event::loop. 43Coro::Event::loop.
36 44
45Please note that even programs or modules (such as
46L<Coro::Handle|Coro::Handle>) that use "traditional"
47event-based/continuation style will run more efficient with this module
48then when using only Event.
49
50=head1 WARNING
51
52Please note that Event does not support coroutines or threads. That
53means that you B<MUST NOT> block in an event callback. Again: In Event
54callbacks, you I<must never ever> call a Coroutine function that blocks
55the current coroutine.
56
57While this seems to work superficially, it will eventually cause memory
58corruption and often results in deadlocks.
59
60Best practise is to always use B<Coro::unblock_sub> for your callbacks.
61
62=head1 SEMANTICS
63
64Whenever Event blocks (e.g. in a call to C<one_event>, C<loop> etc.),
65this module cede's to all other coroutines with the same or higher
66priority. When any coroutines of lower priority are ready, it will not
67block but run one of them and then check for events.
68
69The effect is that coroutines with the same or higher priority than
70the blocking coroutine will keep Event from checking for events, while
71coroutines with lower priority are being run, but Event checks for new
72events after every cede.
73
74=head1 FUNCTIONS
75
37=over 4 76=over 4
38 77
39=cut 78=cut
40 79
41package Coro::Event; 80package Coro::Event;
42 81
43BEGIN { eval { require warnings } && warnings->unimport ("uninitialized") } 82no warnings;
44 83
45use Carp; 84use Carp;
46no warnings; 85no warnings;
47 86
48use Coro; 87use Coro;
88use Coro::Timer;
49use Event qw(loop unloop); # we are re-exporting this, cooool! 89use Event qw(loop unloop); # we are re-exporting this, cooool!
50 90
51use XSLoader; 91use XSLoader;
52 92
53use base Exporter::; 93use base Exporter::;
54 94
55our @EXPORT = qw(loop unloop sweep reschedule); 95our @EXPORT = qw(loop unloop sweep);
56 96
57BEGIN { 97BEGIN {
58 our $VERSION = 1.5; 98 our $VERSION = 4.6;
59 99
60 local $^W = 0; # avoid redefine warning for Coro::ready; 100 local $^W = 0; # avoid redefine warning for Coro::ready;
61 XSLoader::load __PACKAGE__, $VERSION; 101 XSLoader::load __PACKAGE__, $VERSION;
62} 102}
63 103
64=item $w = Coro::Event->flavour(args...) 104=item $w = Coro::Event->flavour (args...)
65 105
66Create and return a watcher of the given type. 106Create and return a watcher of the given type.
67 107
68Examples: 108Examples:
69 109
72 112
73=cut 113=cut
74 114
75=item $w->next 115=item $w->next
76 116
77Return the next event of the event queue of the watcher. 117Wait for and return the next event of the event queue of the watcher. The
118returned event objects support two methods only: C<hits> and C<got>, both
119of which return integers: the number this watcher was hit for this event,
120and the mask of poll events received.
78 121
79=cut 122=cut
80 123
81=item do_flavour(args...) 124=item do_flavour args...
82 125
83Create a watcher of the given type and immediately call it's next 126Create a watcher of the given type and immediately call it's next method,
127returning the event.
128
84method. This is less efficient then calling the constructor once and the 129This is less efficient then calling the constructor once and the next
85next method often, but it does save typing sometimes. 130method often, but it does save typing sometimes.
86 131
87=cut 132=cut
88 133
89for my $flavour (qw(idle var timer io signal)) { 134for my $flavour (qw(idle var timer io signal)) {
90 push @EXPORT, "do_$flavour"; 135 push @EXPORT, "do_$flavour";
98 143
99 shift eq Coro::Event:: 144 shift eq Coro::Event::
100 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method"; 145 or croak "event constructor \"Coro::Event->$flavour\" must be called as a static method";
101 146
102 my $w = $new->($class, 147 my $w = $new->($class,
103 desc => $flavour, 148 desc => $flavour,
104 @_, 149 @_,
105 parked => 1, 150 parked => 1,
106 ); 151 );
152
107 _install_std_cb($w, $type); 153 _install_std_cb $w, $type;
108 bless $w, $class; # reblessing due to broken Event 154
155 # reblessing due to Event being broken
156 bless $w, $class
109 }; 157 };
110 *{ $flavour } = $coronew; 158 *{ $flavour } = $coronew;
111 *{"do_$flavour"} = sub { 159 *{"do_$flavour"} = sub {
112 unshift @_, Coro::Event::; 160 unshift @_, Coro::Event::;
113 my $e = (&$coronew)->next; 161 @_ = &$coronew;
114 $e->cancel; # $e === $e->w 162 &Coro::schedule while &_next;
115 $e; 163 $_[0]->cancel;
164 &_event
116 }; 165 };
117} 166}
118 167
119# double calls to avoid stack-cloning ;() 168# do schedule in perl to avoid forcing a stack allocation.
120# is about 10% slower, though. 169# this is about 10% slower, though.
121sub next($) { 170sub next($) {
122 &Coro::schedule if &_next; $_[0]; 171 &Coro::schedule while &_next;
172 &_event
123} 173}
124 174
175sub Coro::Event::Event::hits { $_[0][3] }
125sub Coro::Event::w { $_[0] } 176sub Coro::Event::Event::got { $_[0][4] }
126sub Coro::Event::prio { $_[0]{Coro::Event}[3] }
127sub Coro::Event::hits { $_[0]{Coro::Event}[4] }
128sub Coro::Event::got { $_[0]{Coro::Event}[5] }
129 177
130=item sweep 178=item sweep
131 179
132Similar to Event::one_event and Event::sweep: The idle task is called once 180Similar to Event::one_event and Event::sweep: The idle task is called once
133(this has the effect of jumping back into the Event loop once to serve new 181(this has the effect of jumping back into the Event loop once to serve new
139into the Event dispatcher. 187into the Event dispatcher.
140 188
141=cut 189=cut
142 190
143sub sweep { 191sub sweep {
144 Event::one_event(0); # for now 192 Event::one_event 0; # for now
145} 193}
146 194
147=item $result = loop([$timeout]) 195=item $result = loop([$timeout])
148 196
149This is the version of C<loop> you should use instead of C<Event::loop> 197This is the version of C<loop> you should use instead of C<Event::loop>
150when using this module - it will ensure correct scheduling in the presence 198when using this module - it will ensure correct scheduling in the presence
151of events. 199of events.
152 200
153=begin comment
154
155Unlike loop's counterpart it is not an error when no watchers are active -
156loop silently returns in this case, as if unloop(undef) were called.
157
158=end comment
159
160=cut
161
162# no longer do something special - it's done internally now
163
164#sub loop(;$) {
165# #local $Coro::idle = $Coro::current;
166# #Coro::schedule; # become idle task, which is implicitly ready
167# &Event::loop;
168#}
169
170=item unloop([$result]) 201=item unloop([$result])
171 202
172Same as Event::unloop (provided here for your convinience only). 203Same as Event::unloop (provided here for your convinience only).
173 204
174=cut 205=cut
175 206
176$Coro::idle = new Coro sub { 207# very inefficient
208our $event_idle = new Coro sub {
177 while () { 209 while () {
178 Event::one_event; # inefficient 210 &Event::one_event;
179 Coro::schedule; 211 &Coro::schedule;
180 } 212 }
181}; 213};
214$event_idle->{desc} = "[Event idle process]";
182 215
183# provide hooks for Coro::Timer 216$Coro::idle = sub { $event_idle->ready };
184
185package Coro::Timer;
186
187unless ($override) {
188 $override = 1;
189 *_new_timer = sub {
190 Event->timer(at => $_[0], cb => $_[1]);
191 };
192}
193 217
1941; 2181;
219
220=back
195 221
196=head1 AUTHOR 222=head1 AUTHOR
197 223
198 Marc Lehmann <schmorp@schmorp.de> 224 Marc Lehmann <schmorp@schmorp.de>
199 http://home.schmorp.de/ 225 http://home.schmorp.de/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines