ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/AnyEvent.pm
Revision: 1.33
Committed: Mon Nov 24 07:55:28 2008 UTC (15 years, 6 months ago) by root
Branch: MAIN
CVS Tags: rel-5_1, rel-5_11
Changes since 1.32: +1 -1 lines
Log Message:
5.1

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 root 1.32 All you have to do is C<use Coro::AnyEvent> and then you can run
27 root 1.2 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 root 1.32 this kind of integration well, and consequently, AnyEvent cannot offer the
38     functionality required by this module, so we need to improvise.
39 root 1.2
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 root 1.32 The callback for that timer will C<cede> to other coroutines of the
56     same or higher priority for as long as such coroutines exists. This has
57     the effect of running all coroutines that have work to do untill all
58     coroutines block to wait for external events.
59 root 1.2
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 root 1.32 event loop, usually the main program, which usually has a priority of
67     C<0>.
68 root 1.2
69 root 1.4 =item * provide a suitable idle callback.
70 root 1.2
71     In addition to hooking into C<ready>, this module will also provide a
72 root 1.32 C<$Coro::idle> handler that runs the event loop. It is best not to take
73     advantage of this too often, as this is rather inefficient, but it should
74     work perfectly fine.
75 root 1.4
76     =item * provide overrides for AnyEvent's condvars
77    
78     This module installs overrides for AnyEvent's condvars. That is, when
79     the module is loaded it will provide its own condition variables. This
80 root 1.30 makes them coroutine-safe, i.e. you can safely block on them from within a
81 root 1.4 coroutine.
82    
83     =item * lead to data corruption or worse
84    
85 root 1.32 As C<unblock_sub> cannot be used by this module (as it is the module
86     that implements it, basically), you must not call into the event
87     loop recursively from any coroutine. This is not usually a difficult
88 root 1.4 restriction to live with, just use condvars, C<unblock_sub> or other means
89     of inter-coroutine-communications.
90    
91     If you use a module that supports AnyEvent (or uses the same event loop
92     as AnyEvent, making the compatible), and it offers callbacks of any kind,
93     then you must not block in them, either (or use e.g. C<unblock_sub>), see
94     the description of C<unblock_sub> in the L<Coro> module.
95    
96     This also means that you should load the module as early as possible,
97     as only condvars created after this module has been loaded will work
98     correctly.
99 root 1.1
100 root 1.7 =back
101    
102 root 1.1 =cut
103    
104     package Coro::AnyEvent;
105    
106     no warnings;
107     use strict;
108    
109     use Coro;
110     use AnyEvent ();
111    
112 root 1.33 our $VERSION = 5.1;
113 root 1.1
114 root 1.5 #############################################################################
115     # idle handler
116    
117 root 1.9 our $IDLE;
118 root 1.1
119 root 1.5 #############################################################################
120     # 0-timeout idle emulation watcher
121    
122 root 1.1 our $ACTIVITY;
123    
124     sub _activity {
125     $ACTIVITY ||= AnyEvent->timer (after => 0, cb => \&_schedule);
126     }
127    
128 root 1.14 Coro::_set_readyhook (\&AnyEvent::detect);
129 root 1.8
130     AnyEvent::post_detect {
131 root 1.10 unshift @AnyEvent::CondVar::ISA, "Coro::AnyEvent::CondVar";
132 root 1.5
133 root 1.8 Coro::_set_readyhook undef;
134    
135     my $model = $AnyEvent::MODEL;
136 root 1.1
137 root 1.10 if ($model eq "AnyEvent::Impl::EV") {
138 root 1.1 require Coro::EV;
139 root 1.10 } elsif ($model eq "AnyEvent::Impl::Event") {
140 root 1.1 require Coro::Event;
141     } else {
142     Coro::_set_readyhook \&_activity;
143 root 1.9
144     $IDLE = new Coro sub {
145 root 1.32 my $one_event = AnyEvent->can ("one_event");
146 root 1.9 while () {
147 root 1.32 $one_event->();
148     Coro::schedule;
149 root 1.9 }
150     };
151     $IDLE->{desc} = "[AnyEvent idle process]";
152    
153 root 1.32 $Coro::idle = $IDLE;
154 root 1.1 }
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