ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/AnyEvent.pm
Revision: 1.28
Committed: Thu Nov 13 17:32:01 2008 UTC (15 years, 6 months ago) by root
Branch: MAIN
CVS Tags: rel-4_912
Changes since 1.27: +1 -1 lines
Log Message:
4.912

File Contents

# Content
1 =head1 NAME
2
3 Coro::AnyEvent - integrate coroutines into AnyEvent
4
5 =head1 SYNOPSIS
6
7 use Coro;
8 use Coro::AnyEvent;
9
10 # use coro within an AnyEvent environment
11
12 =head1 INTRODUCTION
13
14 When one naively starts to use coroutines in Perl, one will quickly run
15 into the problem that coroutines that block on a syscall (sleeping,
16 reading from a socket etc.) will block all coroutines.
17
18 If one then uses an event loop, the problem is that the event loop has
19 no knowledge of coroutines and will not run them before it polls for new
20 events, again blocking the whole process.
21
22 This module integrates coroutines into any event loop supported by
23 AnyEvent, combining event-based programming with coroutine-based
24 programming in a natural way.
25
26 All you have to do is C<use Coro::AnyEvent> and then you can run a
27 coroutines freely.
28
29 =head1 DESCRIPTION
30
31 This module autodetects the event loop used (by relying on L<AnyEvent>)
32 and will either automatically defer to the high-performance L<Coro::EV> or
33 L<Coro::Event> modules, or will use a generic integration into any event
34 loop supported by L<AnyEvent>.
35
36 Unfortunately, few event loops (basically only L<EV> and L<Event>) support
37 this kind of integration well, and therefore AnyEvent cannot offer the
38 required functionality.
39
40 Here is what this module does when it has to work with other event loops:
41
42 =over 4
43
44 =item * run ready coroutines before blocking the process
45
46 Each time a coroutine is put into the ready queue (and there are no other
47 coroutines in the ready queue), a timer with an C<after> value of C<0> is
48 registered with AnyEvent.
49
50 This creates something similar to an I<idle> watcher, i.e. a watcher
51 that keeps the event loop from blocking but still polls for new
52 events. (Unfortunately, some badly designed event loops (e.g. Event::Lib)
53 don't support a timeout of C<0> and will always block for a bit).
54
55 The callback for that timer will C<cede> to other coroutines of the same
56 or higher priority for as long as such coroutines exists. This has the
57 effect of running all coroutines that have work to do will all coroutines
58 block to wait for external events.
59
60 If no coroutines of equal or higher priority are ready, it will cede
61 to any coroutine, but only once. This has the effect of running
62 lower-priority coroutines as well, but it will not keep higher priority
63 coroutines from receiving new events.
64
65 The priority used is simply the priority of the coroutine that runs the
66 event loop, usually the main program, and the priority is usually C<0>.
67
68 =item * provide a suitable idle callback.
69
70 In addition to hooking into C<ready>, this module will also provide a
71 C<$Coro::idle> handler that runs the event loop. It is best not to rely on
72 this, as this is rather inefficient.
73
74 =item * provide overrides for AnyEvent's condvars
75
76 This module installs overrides for AnyEvent's condvars. That is, when
77 the module is loaded it will provide its own condition variables. This
78 makes the coroutine-safe, i.e. you can safely block on them from within a
79 coroutine.
80
81 =item * lead to data corruption or worse
82
83 As C<unblock_sub> cannot be by this module (as it is the module that
84 implements it, basically), you must not call into the event loop
85 recursively from any coroutine. This is not usually a difficult
86 restriction to live with, just use condvars, C<unblock_sub> or other means
87 of inter-coroutine-communications.
88
89 If you use a module that supports AnyEvent (or uses the same event loop
90 as AnyEvent, making the compatible), and it offers callbacks of any kind,
91 then you must not block in them, either (or use e.g. C<unblock_sub>), see
92 the description of C<unblock_sub> in the L<Coro> module.
93
94 This also means that you should load the module as early as possible,
95 as only condvars created after this module has been loaded will work
96 correctly.
97
98 =back
99
100 =cut
101
102 package Coro::AnyEvent;
103
104 no warnings;
105 use strict;
106
107 use Coro;
108 use AnyEvent ();
109
110 our $VERSION = 4.912;
111
112 #############################################################################
113 # idle handler
114
115 our $IDLE;
116
117 #############################################################################
118 # 0-timeout idle emulation watcher
119
120 our $ACTIVITY;
121
122 sub _activity {
123 $ACTIVITY ||= AnyEvent->timer (after => 0, cb => \&_schedule);
124 }
125
126 Coro::_set_readyhook (\&AnyEvent::detect);
127
128 AnyEvent::post_detect {
129 unshift @AnyEvent::CondVar::ISA, "Coro::AnyEvent::CondVar";
130
131 Coro::_set_readyhook undef;
132
133 my $model = $AnyEvent::MODEL;
134
135 if ($model eq "AnyEvent::Impl::EV") {
136 require Coro::EV;
137 } elsif ($model eq "AnyEvent::Impl::Event") {
138 require Coro::Event;
139 } else {
140 Coro::_set_readyhook \&_activity;
141
142 $IDLE = new Coro sub {
143 while () {
144 AnyEvent->one_event;
145 &Coro::schedule;
146 }
147 };
148 $IDLE->{desc} = "[AnyEvent idle process]";
149
150 $Coro::idle = sub {
151 local $ACTIVITY = 1; # hack to keep it from being set by the ready call
152 $IDLE->ready;
153 };
154 }
155 };
156
157 #############################################################################
158 # override condvars
159
160 package Coro::AnyEvent::CondVar;
161
162 sub _send {
163 (delete $_[0]{_ae_coro})->ready if $_[0]{_ae_coro};
164 }
165
166 sub _wait {
167 while (!$_[0]{_ae_sent}) {
168 local $_[0]{_ae_coro} = $Coro::current;
169 Coro::schedule;
170 }
171 }
172
173 1;
174
175 =head1 SEE ALSO
176
177 L<AnyEvent>, to see which event loops are supported, L<Coro::EV> and
178 L<Coro::Event> for more efficient and more correct solutions (they will be
179 used automatically if applicable).
180
181 =head1 AUTHOR
182
183 Marc Lehmann <schmorp@schmorp.de>
184 http://home.schmorp.de/
185
186 =cut
187