NAME
Coro::AnyEvent - integrate coroutines into AnyEvent
SYNOPSIS
use Coro;
use Coro::AnyEvent;
# use coro within an AnyEvent environment
INTRODUCTION
When one naively starts to use coroutines in Perl, one will quickly run into the problem that coroutines that block on a syscall (sleeping, reading from a socket etc.) will block all coroutines.
If one then uses an event loop, the problem is that the event loop has no knowledge of coroutines and will not run them before it polls for new events, again blocking the whole process.
This module integrates coroutines into any event loop supported by AnyEvent, combining event-based programming with coroutine-based programming in a natural way.
All you have to do is use Coro::AnyEvent
and then you can run a coroutines freely.
DESCRIPTION
This module autodetects the event loop used (by relying on AnyEvent) and will either automatically defer to the high-performance Coro::EV or Coro::Event modules, or will use a generic integration into any event loop supported by AnyEvent.
Unfortunately, few event loops (basically only EV and Event) support this kind of integration well, and therefore AnyEvent cannot offer the required functionality.
Here is what this module does when it has to work with other event loops:
run ready coroutines before blocking the process
Each time a coroutine is put into the ready queue (and there are no other coroutines in the ready queue), a timer with an
after
value of0
is registered with AnyEvent.This creates something similar to an idle watcher, i.e. a watcher that keeps the event loop from blocking but still polls for new events. (Unfortunately, some badly designed event loops (e.g. Event::Lib) don't support a timeout of
0
and will always block for a bit).The callback for that timer will
cede
to other coroutines of the same or higher priority for as long as such coroutines exists. This has the effect of running all coroutines that have work to do will all coroutines block to wait for external events.If no coroutines of equal or higher priority are ready, it will cede to any coroutine, but only once. This has the effect of running lower-priority coroutines as well, but it will not keep higher priority coroutines from receiving new events.
The priority used is simply the priority of the coroutine that runs the event loop, usually the main program, and the priority is usually
0
.provide a suitable idle callback.
In addition to hooking into
ready
, this module will also provide a$Coro::idle
handler that runs the event loop. It is best not to rely on this, as this is rather inefficient.provide overrides for AnyEvent's condvars
This module installs overrides for AnyEvent's condvars. That is, when the module is loaded it will provide its own condition variables. This makes them coroutine-safe, i.e. you can safely block on them from within a coroutine.
lead to data corruption or worse
As
unblock_sub
cannot be by this module (as it is the module that implements it, basically), you must not call into the event loop recursively from any coroutine. This is not usually a difficult restriction to live with, just use condvars,unblock_sub
or other means of inter-coroutine-communications.If you use a module that supports AnyEvent (or uses the same event loop as AnyEvent, making the compatible), and it offers callbacks of any kind, then you must not block in them, either (or use e.g.
unblock_sub
), see the description ofunblock_sub
in the Coro module.This also means that you should load the module as early as possible, as only condvars created after this module has been loaded will work correctly.
SEE ALSO
AnyEvent, to see which event loops are supported, Coro::EV and Coro::Event for more efficient and more correct solutions (they will be used automatically if applicable).
AUTHOR
Marc Lehmann <schmorp@schmorp.de>
http://home.schmorp.de/