ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/AnyEvent.pm
Revision: 1.4
Committed: Fri May 9 23:50:07 2008 UTC (16 years ago) by root
Branch: MAIN
Changes since 1.3: +30 -5 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     our $IDLE = new Coro sub {
111     while () {
112     AnyEvent->one_event;
113     &Coro::schedule;
114     }
115     };
116     $IDLE->{desc} = "[AnyEvent idle process]";
117    
118     our $ACTIVITY;
119    
120     sub _activity {
121     $ACTIVITY ||= AnyEvent->timer (after => 0, cb => \&_schedule);
122     }
123    
124     sub _detect {
125     my $model = AnyEvent::detect;
126    
127     if ($model eq "AnyEvent::Impl::EV" || $model eq "AnyEvent::Impl::CoroEV") {
128     require Coro::EV;
129     Coro::_set_readyhook undef;
130     } elsif ($model eq "AnyEvent::Impl::Event" || $model eq "AnyEvent::Impl::CoroEvent") {
131     require Coro::Event;
132     Coro::_set_readyhook undef;
133     } else {
134     Coro::_set_readyhook \&_activity;
135     $Coro::idle = sub {
136     local $ACTIVITY = 1; # hack to keep it from being set
137     $IDLE->ready;
138     };
139     }
140     }
141    
142     Coro::_set_readyhook \&_detect;
143    
144     1;
145    
146 root 1.3 =head1 SEE ALSO
147    
148     L<AnyEvent>, to see which event loops are supported, L<Coro::EV> and
149     L<Coro::Event> for more efficient and more correct solutions (they will be
150     used automatically if applicable).
151    
152 root 1.1 =head1 AUTHOR
153    
154     Marc Lehmann <schmorp@schmorp.de>
155     http://home.schmorp.de/
156    
157     =cut
158