=head1 NAME

Event - Event loop processing

=head1 SYNOPSIS

 use Event qw(loop unloop);
 
 # initialize application
 Event->type(callback => sub { ... },
             typespecific => 1
            );
    
 my $ret = loop();
    
 # and some callback will call
 unloop('ok');

=head1 DESCRIPTION

The Event module provide a central facility to watch for various types
of events and invoke a callback when these events occur.  The key idea
is to delay the handling of events so they can be dispatched in order
of priority and also when it is known to be safe for callbacks to
execute.

Events (the occurance of such) are handled by event watchers.  The
creation and configuration of event watchers is the primary topic of
the rest of this document.
 
The following functions control and interrogate the event loop as a
whole:

=over 4

=item $result = loop([$timeout])

Will enter a loop that calls one_event() until unloop() is called.
The argument passed to unloop() is the return value of loop().  Loops
can be nested.

=item unloop($result)

Make the inner-most loop() return with $result.

=item unloop_all()

Cause all pending loop()s to return immediately.  This is not
implemented with an exception.  It works by effectly calling
C<unloop(undef)> for each pending loop.

=item sweep([$max_prio])

Queue all pending events and process the ones with priority higher
than $max_prio.  The default is to process all events except idle
events.  (Idle events are ignored by sweep.)

=item one_event([$timeout])

If any events have happened, invoke the corresponding callback of the
highest priority event.  If no event has happened yet, block until
forever or until $timeout.  Using this API is not recommended because
it doesn't trap exceptions.

=item all_events()

Returns a list of all event watchers (including cancelled events).

=item all_running()

Returns a list of all event watchers with active callbacks.  The
watchers are returned in order of most recent to least recent.

=item all_queued()

Returns all queued event watchers in order of priority.

=item all_idle()

Returns all event watchers in the idle queue.

=back

=head1 EVENT WATCHER CONSTRUCTORS

All watchers are constructed in one of the following ways:

  $w = Event->type( [attr1 => $value,]... );
 
or
 
  use Event::type;
  $w = Event::type( [attr1 => $value,]...);

Where I<type> is substituted with the kind of watcher.  Built in types
include: idle, io, timer, watchvar, signal, and process.

The new watcher object is returned initialized with the attributes
passed to the constructor.  The watcher is already active.  More
precisely, the watcher object is "started" and already waiting for
events (see C<$event-E<gt>start> below).

=head1 SHARED WATCHER ATTRIBUTES

Watchers are configured with attributes (also called properties).
This is a fancy way of saying that a watcher object works like hash
reference.  For example:

   $watcher->{callback} = \&some_code;

   print "$watcher->{count} events happened; Wow!\n";

The following attributes are supported by all types of watchers.  Most
watchers types also offer additional attributes.

=over 4

=item id => $int

An integer that identifies this event.  This attribute is read-only.
You should use this to test for equality (until the equality test for
tied objects is fixed).

=item callback => \&code

=item callback => [$class_or_object, $method]

The function or method to call when an event happens.  The callback is
invoked with a reference to the $event as its only argument.

Perhaps you are wondering what happens if something goes wrong and an
untrapped C<die> occurs within your callback?  $Event::DIED is just
for this purpose.  When you call C<loop> or C<sweep>, an exception
context is established that lasts throughout event processing. If an
exception is detected, C<$Event::DIED> is invoked like this:
 
  $Event::DIED->($watcher, $@);
 
The default hook uses C<warn> to print the exception.  After C<DIED>
returns, event processing continues as if nothing happened.  If you'd
like to see more detailed output you can use the verbose handler
(below) or write your own.

  $Event::DIED = \&Event::verbose_exception_handler;

=item count => $int

The number of times this event has happened since last time the
callback was invoked.  This attribute is read-only.  It is reset to
zero when the callback completes or as soon as you call one_event(),
loop(), or now() within the callback.

=item priority => $int

The priority is used to order events queued for processing.  Available
priorities range from -1 to 6, inclusive.  Lower numbers are higher
priority (-1 is the highest priority, 6 is the lowest).  When multiple
events have happened, the event with the highest priority are serviced
first.

A negative priority is interpreted to mean that the callback should be
invoked immediately when the event happens.  Use this with caution.
While it may seem advantageous to use negative priorities, it defeats
the purpose of having an event queue in the first place.

The -priority passed as argument to the event constructor is treated
differently.  It is an offset from the default priority of the event
type.

=item desc => $string

Some identifying name.  If not passed to the constructor it will be
initialized with some string that attempts to identify the location in
the source code where the event object was constructed.

=item flags => $bits
 
The flag attribute encodes some information about the state of an
event.  [XXX Fill in exact bits]

=item repeat => $bool

The repeat flag controls if callback should be one-shot or if the
watcher should continue waiting for new events of this kind occur.
The default depends on the type of watcher.  It defaults to TRUE for
the I<io>, I<signal>, I<watchvar> types.

=item debug => $bool

Debugging can be activated per watcher.  When debugging is enabled,
$Event::DebugLevel is treated as two levels higher for this watcher.  A
level of 1, 2, 3, or 4 give progressively more noise on STDERR.

=item reentrant => $bool

By default, callbacks are allowed to invoke C<sweep> or C<loop> which
in turn may invoke the same callback again recursively.  This can be
useful but can also be confusing.  Turn off this feature by setting
reentrant to false.  This will cause an active watcher to be suspended
during recursive calls to C<sweep> or C<loop>.

=back

=head1 SHARED WATCHER METHODS

The following methods can be invoked on an event:

=over 4

=item $watcher->start

Activate the watcher.  Many constructors will automatically invoke
$watcher->start.

=item $watcher->again

The same as the C<start> method except in the case of events that do
something special when they repeat.  For example, repeating timers
recalcuate their alarm time using their C<interval> parameter.

=item $watcher->cancel

Don't look for any events any more.  Note that the watcher can be
reactivated by calling the C<start> or C<again> methods.

=item $watcher->now

Make the watcher callback trigger now.  Note that the callback may or
may not be run immediately depending upon its priority.

=item ($runs, $elapse) = $watcher->stats( $sec )

Return statistics for the last $sec seconds of operation.  Two numbers
are returned: the number of times the callback has been invoked and
the number of seconds spent within the callback.  Statistics must have
been enabled.  Also see L<NetServer::ProcessTop>.

=back

=head1 WATCHER TYPES

=over 4

=item idle

The callback is invoked only if no other event is pending.

=item watchvar

Extra attribute: variable => \$var

Triggered when the value of C<$var> is changed.

=item timer

Extra attributes: at => $time, interval => $sec, hard => $bool

The callback in invoked at the specified (-at) point in time.  The
$time and $sec arguments can be fractional seconds.

If -interval set, then the callback will be automatically resheduled
after this amount of time.  Due to lags in the event loop, the
-interval timeout may already be in the past.  If the -hard flag is
set, then event will be queued for execution immediately.  Otherwise,
the new timeout will be calculated relative to the current time (this
is the default).

The constructor also accepts an -after attribute as argument.  The
current time will be added to this value and stored in the object as
the -at attribute.

=item io

Extra attributes: handle => $fh, events => "rwe", got => "rwet",
[timeout => $seconds]

The callback is invoked when the filehandle has data to be read,
written, or pending exceptions.  The -handle attribute specifies which
filehandle to watch.  It can be a glob, an IO::Handle object, or a
file number (file descriptor).  The -events specify which events to
look for.  It consist of a string with letters representing flags.
"r" means to trigger when the handle is readable.  "w" means to
trigger when the handle is writable.  "e" to trigger when the handle
has pending exceptions.

When the callback is invoked, then the -got attribute tell you which
-events triggered.  The -got attribute is read-only.  If you think
that testing for letters is too slow, you can also use -got as a bit
mask.  The bit constants can be exported from Event.

Note that it is your choice whether to have multiple watchers per
filehandle or a single watcher that handles all event flavors.

=item signal

Extra attribute: signal => $str

The callback will be invoked when the specified signal has been
received by this process.  The $str is a string like "INT", "QUIT",...

While you are welcome to handle the C<CHLD> signal yourself, you can
also use the C<process> watcher type.

=item process

Extra attribute: pid => $int, [timeout => $seconds]

Callback is invoked when the process with the given PID exits.  If no
pid is given then callback will be invoked when any child process
terminates that does not have it's own event handler.

=item semaphore

Not implemented.

=item msg

Not implemented.

=back
    
=head1 C API

Event also has a direct C API for performance critical applications.
See L<Event::MakeMaker>.

=head1 ALSO SEE

L<NetServer::ProcessTop> and L<Time::HiRes>

=head1 SUPPORT

This extension is discussed on the perl-loop@perl.org mailing list.

=head1 AUTHORS

Joshua Pritikin E<lt>F<bitset@mindspring.com>E<gt>

Initial 0.01 implementation by Graham Barr
E<lt>F<gbarr@pobox.com>E<gt>.  Also, contributions from:

 Gisle Aas E<lt>F<gisle@aas.no>E<gt>
 Mark Mielke E<lt>F<Mark.Mielke.markm@nt.com>E<gt>
 Nick Ing-Simmons E<lt>F<nick@ni-s.u-net.com>E<gt>

=head1 COPYRIGHT

Copyright © 1997-1998 Joshua Nathaniel Pritikin & Graham Barr.  All
rights reserved.  This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.

=cut
