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