—=head1 NAME
UniEvent::Loop - The event loop object
=head1 SYNOPSIS
my $loop = UniEvent::Loop->new;
my $timer = UE::timer 1, sub { ... }, $loop;
$loop->run; # exists as soon as there is nothing to do
$loop->delay(sub { say "executed once. soon, but not now" });
$loop->update_time;
say "current unix epoch: ", $loop->now, " (milliseconds)";
=head1 DESCRIPTION
The event loop is the central part of UniEvent's functionality.
It takes care of polling for i/o and scheduling callbacks to be run based on different sources of events.
Contrary to L<AnyEvent> and L<EV>, where there is only one event loop instance (singleton), with L<UniEvent> it is possible
to have many independent loops. The most close to the <AnyEvent> approach is, probably, the B<default loop> in <UniEvent>.
When a new handle (I/O event listener) is created, if the C<$loop> parameter is ommited (or it is C<undef>ined), then the default loop is used.
Event loops are B<independent> each from other. That means, for example, if there are two loop instances,
my $loop1 = UniEvent::Loop->new;
my $loop2 = UniEvent::Loop->new;
...;
$loop1->run;
Only handles from C<$loop1> will be polled for I/O.
It should be noted that handles can't be transferred between different loops.
That's why it is possible to specify it in handle constructor only.
=head1 FUNCTIONS
=head2 default(), ALIAS default_loop()
=head2 global(), ALIAS global_loop()
Returns a singleton loop object.
The only difference between C<default()> and C<global()> can be noted on threaded perls in case if you use multiple threads in your application.
C<default()> loop is B<thread-local>, i.e. it a singleton, but it is different in each thread;
while C<global()> loop is the same loop instance for the whole application.
C<global()> always returns main thread's C<default()> loop.
It is not recommended to use C<global()>, because loop objects are B<not> thread-safe and thus using C<global()> may lead to undefined behaviour if
used from different threads. It exists only for rare cases when you definitely know what you're doing.
For many cases, when event loop parameter is ommited, the C<default()> loop is used.
NOTE: for single-threaded applications, C<global()> and C<default()> returns the same loop object.
=head1 METHODS
=head2 new([$backend = default])
Constructs new event loop object using the specified backend. If
the C<$backend> is not specified, then the default backend is used.
See L<UniEvent/default_backend()>
=head2 is_default()
Returns C<true> if the loop is the default loop (for the current thread).
=head2 is_global()
Returns C<true> if the loop is the application global loop.
=head2 alive()
Returns C<true> if there are active handles or requests in the loop.
=head2 now()
Return the current timestamp I<in milliseconds>. The value is cached for each
event loop iteration. The timestamp is monotonically increased at arbitrary
point of time.
=head2 update_time()
Updates cached "now" value for the loop. It is useful, if in a callback or
handle there is a time-sensitive blocking I/O operation, where it is undesirable
to let the following callbacks have outdated "now" value.
=head2 run()
Runs the event loop until there are no more active and referenced handles or requests.
Returns C<true> if the loop was stopped and there are still active handles or requests.
This method B<MAY be non-reenterant>, i.e. must not be called from an event callback, as many backends does not support recursive B<run>.
=head2 run_once()
Poll for i/o once (may block until there are pending callbacks).
Returns C<false> when done (no active handles or requests left), or C<true> if more callbacks are expected
(meaning you should run the event loop again sometime in the future).
This method B<MAY be non-reenterant>, i.e. must not be called from an event callback, as many backends does not support recursive B<run>.
=head2 run_nowait()
Poll for i/o once but don’t block if there are no pending callbacks.
Returns C<false> if done (no active handles or requests left), or C<true> if more callbacks are expected
(meaning you should run the event loop again sometime in the future).
This method B<MAY be non-reenterant>, i.e. must not be called from an event callback, as many backends does not support recursive B<run>.
=head2 stop()
Stop the event loop, causing C<run> to end as soon as possible. This will happen not
sooner than the next loop iteration. If this function was called before blocking for
i/o, the loop won't block for i/o on this iteration.
=head2 handles()
Returns array of handles, associated with the loop.
It is recommended for use only for debugging.
=head2 delay($callback)
This is a convenient one-shot callback, which will be invoked "a little bit later".
"A little bit later" is somewhat unspecified, but normally it is on the next loop iteration; although, it might be invoked don't
waiting the next iteration.
It is guaranteed that callback will not be called until we return from the current callback code flow (return to the loop internal code).
In non-void context it returns the delay cancellation guard. In void context the
provided callback is non-cancellable.
The callback can be cancelled either via C<undef>'ing C<$guard> or via calling C<cancel_delay> method.
my $guard = $loop->delay(sub { say 'hello' });
$guard = undef if ($some_condition);
$loop->run;
=head2 cancel_delay($delay_guard)
Cancels previously set delay. Does nothing if it's too late (callback has already been called).
=head2 fork_event()
Returns L<XS::Framework::CallbackDispatcher> for setting callback which will be invoked when the application C<fork()>s.
See L<UniEvent/"EVENT CALLBACKS"> for more info.
Callback is called on behalf of a child process, after all fork-related work for event loop is done (see L<UniEvent/FORK>).
The callback will receive single argument - the event loop object.
$loop->fork_event->add(sub {
my $loop = shift;
...
});
=head2 resolver()
Returns per-loop L<UniEvent::Resolver> object.
This resolver object does not hold the loop, so if you keep a reference to it, you must not use it after it's loop death (otherwise exception will be thrown).
=head2 track_load_average($seconds)
Starts tracking load average on the loop. Tracked value is the average loop busy load for last C<$seconds>. This value is NOT a CPU load, instead
it is somewhat more useful. It is wallclock time that was spent on calling user callbacks (and related stuff) during last C<$seconds> divided by
C<$seconds>. I.e. part of the time, the loop was not in I/O polling, in other words, part of the time the loop was busy and could not receive new events.
This value is more useful than CPU load because even in case of blocking code (waiting for blocking I/O) it will count such time as busy time.
=head2 get_load_average()
Returns loop busy load (value between 0 and 1, where 1 means 100% busy). If C<track_load_average()> wasn't previously enabled, returns 0.
=head2 start_debug_tracer($callback)
This is debug assistant function. The C<$callback> is always invoked upon new
handle binding to the loop. It is expected that the C<$callback> will return
a scalar, which will be linked with the new handle. Later it can be examined
via the C<watch_active_trace> method.
The scalar can be arbitrary value, however, it is the most useful if
it is stacktrace, generated by modules like L<Exception::Backtrace> or L<Devel::Trace>.
=head2 watch_active_trace($callback)
Examines each active non-weakened handle for the attached scalar (backtrace).
Meant to be used with C<start_debug_tracer>. Example:
$loop->start_debug_tracer(sub { Exception::Backtrace::create_backtrace() });
...;
# somewhere inside any handler callback
$loop->watch_active_trace(sub {
my ($handle, $trace) = @_;
say "$handle ", $trace->to_string;
});
...;
$loop->run;
=head1 CAVEATS
Notable difference from the L<AnyEvent> is that L<UniEvent> event loop is B<not reenterant> and leads to undefined behaviour.
E.g.
my $cv = AE::cv;
...
my $t = AE::timer 0.1, 0, sub {
say $cv->recv; # implicitly runs loop nested iteration
};
...
cannot be done with L<UniEvent>. The limitation is imposed by L<libuv|libuv.org> event loop.
This might be changed in future for other backends that support such feature.
However, to our opinion the AE-approach in that case should be discouraged in production code, as it possibly
leads to dead locks (or live locks), and might be allowed in tests only.
=cut