ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/AnyEvent.pm
Revision: 1.19
Committed: Tue Sep 23 00:02:20 2008 UTC (15 years, 8 months ago) by root
Branch: MAIN
CVS Tags: rel-4_747
Changes since 1.18: +1 -1 lines
Log Message:
4.747

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.3 Coro::AnyEvent - integrate coroutines into AnyEvent
4 root 1.1
5     =head1 SYNOPSIS
6    
7     use Coro;
8     use Coro::AnyEvent;
9    
10 root 1.2 # 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 root 1.1
29     =head1 DESCRIPTION
30    
31 root 1.2 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 root 1.4 =over 4
43    
44     =item * run ready coroutines before blocking the process
45    
46 root 1.2 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 root 1.4 =item * provide a suitable idle callback.
69 root 1.2
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 root 1.4 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 root 1.1
98 root 1.7 =back
99    
100 root 1.1 =cut
101    
102     package Coro::AnyEvent;
103    
104     no warnings;
105     use strict;
106    
107     use Coro;
108     use AnyEvent ();
109    
110 root 1.19 our $VERSION = 4.747;
111 root 1.1
112 root 1.5 #############################################################################
113     # idle handler
114    
115 root 1.9 our $IDLE;
116 root 1.1
117 root 1.5 #############################################################################
118     # 0-timeout idle emulation watcher
119    
120 root 1.1 our $ACTIVITY;
121    
122     sub _activity {
123     $ACTIVITY ||= AnyEvent->timer (after => 0, cb => \&_schedule);
124     }
125    
126 root 1.14 Coro::_set_readyhook (\&AnyEvent::detect);
127 root 1.8
128     AnyEvent::post_detect {
129 root 1.10 unshift @AnyEvent::CondVar::ISA, "Coro::AnyEvent::CondVar";
130 root 1.5
131 root 1.8 Coro::_set_readyhook undef;
132    
133     my $model = $AnyEvent::MODEL;
134 root 1.1
135 root 1.10 if ($model eq "AnyEvent::Impl::EV") {
136 root 1.1 require Coro::EV;
137 root 1.10 } elsif ($model eq "AnyEvent::Impl::Event") {
138 root 1.1 require Coro::Event;
139     } else {
140     Coro::_set_readyhook \&_activity;
141 root 1.9
142     $IDLE = new Coro sub {
143     while () {
144     AnyEvent->one_event;
145     &Coro::schedule;
146     }
147     };
148     $IDLE->{desc} = "[AnyEvent idle process]";
149    
150 root 1.1 $Coro::idle = sub {
151 root 1.6 local $ACTIVITY = 1; # hack to keep it from being set by the ready call
152 root 1.1 $IDLE->ready;
153     };
154     }
155 root 1.8 };
156 root 1.5
157     #############################################################################
158     # override condvars
159    
160 root 1.10 package Coro::AnyEvent::CondVar;
161 root 1.5
162 root 1.10 sub _send {
163     (delete $_[0]{_ae_coro})->ready if $_[0]{_ae_coro};
164 root 1.5 }
165    
166 root 1.10 sub _wait {
167     while (!$_[0]{_ae_sent}) {
168     local $_[0]{_ae_coro} = $Coro::current;
169 root 1.5 Coro::schedule;
170     }
171     }
172 root 1.1
173     1;
174    
175 root 1.3 =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 root 1.1 =head1 AUTHOR
182    
183     Marc Lehmann <schmorp@schmorp.de>
184     http://home.schmorp.de/
185    
186     =cut
187