The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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 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 consequently, AnyEvent cannot offer the functionality required by this module, so we need to improvise.

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 of 0 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 untill 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, which usually has a priority of 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 take advantage of this too often, as this is rather inefficient, but it should work perfectly fine.

  • 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 used 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 of unblock_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/