EV-Loop-Async

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

NAME
    EV::Loop::Async - run an EV event loop asynchronously

SYNOPSIS
      use EV::Loop::Async;
  
      my $loop = EV::Loop::Async::default;
      my $timer;
      my $flag;
  
      # create a watcher, but make sure the loop is locked
      {
         $loop->scope_lock; # lock the loop structures
         $timer = $loop->timer (5, 1, sub { $flag = 1 });
         $loop->notify; # tell loop to take note of the timer
      }
  
      1 while $flag; # $flag will be set asynchronously
  
      # implement a critical section, uninterrupted by any callbacks
      {
         $loop->interrupt->scope_block;
         # critical section, no watcher callback interruptions
      }
  
      # stop the timer watcher again - locking is required once more
      {
         $loop->scope_lock; # lock the loop structures
         $timer->stop;
         # no need to notify
      }

DESCRIPTION
    This module implements a rather specialised event loop - it takes a
    normal EV event loop and runs it in a separate thread. That means it
    will poll for events even while your foreground Perl interpreter is busy
    (you don't need to have perls pseudo-threads enabled for this either).

    Whenever the event loop detecs new events, it will interrupt perl and
    ask it to invoke all the pending watcher callbacks. This invocation will
    be "synchronous" (in the perl thread), but it can happen at any time.

    See the documentation for Async::Interrupt for details on when and how
    your perl program can be interrupted (and how to avoid it), and how to
    integrate background event loops into foreground ones.

FAQ
    Why on earth...???
        Sometimes you need lower latency for specific events, but it's too
        heavy to continuously poll for events. And perl already does this
        for you anyways, so this module only uses this existing mechanism.

    When do I have to lock?
        When in doubt, lock. Do not start or stop a watcher, do not create a
        watcher (unless with the "_ns" methods) and do not DESTROY an active
        watcher without locking either.

        Any other event loop modifications need to be done while locked as
        well. So when in doubt, lock (best using "scope_lock").

    Why explicit locking?
        Because I was too lazy to wrap everything and there are probably
        only a few people on this world using this module.

FUNCTIONS, METHODS AND VARIABLES OF THIS MODULE
    $loop = EV::Loop::Async::default
        Return the default loop, usable by all programs. The default loop
        will be created on the first call to "default" by calling , and
        should be used by all programs unless they have special
        requirements.

        The associated Async::Interrupt object is stored in
        $EV::Loop::Async::AI, and can be used to lock critical sections etc.

    $EV::Loop::Async::LOOP
        The default async loop, available after the first call to
        "EV::Loop::Async::default".

    $EV::Loop::Async::INTERRUPT
        The default loop's Async::Interrupt object, for easy access.

        Example: create a section of code where no callback invocations will
        interrupt:

           {
              $EV::Loop::Async::INTERRUPT->scope_block;
              # no default loop callbacks will be executed here.
              # the loop will not be locked, however.
           }

        Example: embed the default EV::Async::Loop loop into the default EV
        loop (note that it could be any other event loop as well).

           my $async_w = EV::io
                            $EV::Loop::Async::LOOP->interrupt->pipe_fileno,
                            EV::READ,
                            sub { };

    $loop = new EV::Loop::Async $flags, [Async-Interrupt-Arguments...]
        This constructor:

        1. creates a new "EV::Loop" (similar "new EV::Loop").
        2. creates a new Async::Interrupt object and attaches itself to it.
        3. creates a new background thread.
        4. runs "$loop->run" in that thread.

        The resulting loop will be running and unlocked when it is returned.

        Example: create a new loop, block it's interrupt object and embed it
        into the foreground AnyEvent event loop. This basically runs the
        "EV::Loop::Async" loop in a synchronous way inside another loop.

           my $loop  = new EV::Loop::Async 0;
           my $async = $loop->interrupt;

           $async->block;

           my $async_w = AnyEvent->io (
              fh => $async->pipe_fileno,
              poll => "r",
              cb => sub {
                 # temporarily unblock to handle events
                 $async->unblock;
                 $async->block;
              },
           );

    $loop->notify
        Wake up the asynchronous loop. This is useful after registering a
        new watcher, to ensure that the background event loop integrates the
        new watcher(s) (which only happens when it iterates, which you can
        force by calling this method).

        Without calling this method, the event loop *eventually* takes
        notice of new watchers, bit when this happens is not well-defined
        (can be instantaneous, or take a few hours).

        No locking is required.

        Example: lock the loop, create a timer, nudge the loop so it takes
        notice of the new timer, then evily busy-wait till the timer fires.

           my $timer;
           my $flag;

           {
              $loop->scope_lock;
              $timer = $loop->timer (1, 0, sub { $flag = 1 });
              $loop->notify;
           }

           1 until $flag;

    $loop->lock
    $loop->unlock
        Lock/unlock the loop data structures. Since the event loop runs in a
        separate thread, you have to lock the loop data structures before
        accessing them in any way. Since I was lazy, you have to do this
        manually.

        You must lock under the same conditions as you would have to lock
        the underlying C library, e.g. when starting or stopping watchers
        (but not when creating or destroying them, but note that create and
        destroy often starts and stops for you, in which case you have to
        lock).

        When in doubt, lock.



( run in 1.030 second using v1.01-cache-2.11-cpan-39bf76dae61 )