ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/AnyEvent.pm
Revision: 1.7
Committed: Sat May 10 00:36:24 2008 UTC (16 years, 1 month ago) by root
Branch: MAIN
Changes since 1.6: +2 -0 lines
Log Message:
*** empty log message ***

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     our $VERSION = '2.2';
111    
112 root 1.5 #############################################################################
113     # idle handler
114    
115 root 1.1 our $IDLE = new Coro sub {
116     while () {
117     AnyEvent->one_event;
118     &Coro::schedule;
119     }
120     };
121     $IDLE->{desc} = "[AnyEvent idle process]";
122    
123 root 1.5 #############################################################################
124     # 0-timeout idle emulation watcher
125    
126 root 1.1 our $ACTIVITY;
127    
128     sub _activity {
129     $ACTIVITY ||= AnyEvent->timer (after => 0, cb => \&_schedule);
130     }
131    
132     sub _detect {
133 root 1.5 unshift @AnyEvent::ISA, "Coro::AnyEvent::Condvar";
134    
135 root 1.1 my $model = AnyEvent::detect;
136    
137     if ($model eq "AnyEvent::Impl::EV" || $model eq "AnyEvent::Impl::CoroEV") {
138     require Coro::EV;
139     Coro::_set_readyhook undef;
140     } elsif ($model eq "AnyEvent::Impl::Event" || $model eq "AnyEvent::Impl::CoroEvent") {
141     require Coro::Event;
142     Coro::_set_readyhook undef;
143     } else {
144     Coro::_set_readyhook \&_activity;
145     $Coro::idle = sub {
146 root 1.6 local $ACTIVITY = 1; # hack to keep it from being set by the ready call
147 root 1.1 $IDLE->ready;
148     };
149     }
150     }
151    
152 root 1.5 if ($AnyEvent::MODEL) {
153     _detect;
154     } else {
155     push @AnyEvent::detect, \&_detect;
156     Coro::_set_readyhook \&AnyEvent::detect;
157     }
158    
159     #############################################################################
160     # override condvars
161    
162     package Coro::AnyEvent::Condvar;
163    
164     use Coro::Signal ();
165    
166     sub condvar {
167     bless [], __PACKAGE__
168     }
169    
170     sub broadcast {
171     $_[0][0] = 1;
172     $_[0][1]->ready if $_[0][1];
173     }
174    
175     sub wait {
176     while (!$_[0][0]) {
177     local $_[0][1] = $Coro::current;
178     Coro::schedule;
179     }
180     }
181 root 1.1
182     1;
183    
184 root 1.3 =head1 SEE ALSO
185    
186     L<AnyEvent>, to see which event loops are supported, L<Coro::EV> and
187     L<Coro::Event> for more efficient and more correct solutions (they will be
188     used automatically if applicable).
189    
190 root 1.1 =head1 AUTHOR
191    
192     Marc Lehmann <schmorp@schmorp.de>
193     http://home.schmorp.de/
194    
195     =cut
196