Coro
view release on metacpan or search on metacpan
Coro/AnyEvent.pm view on Meta::CPAN
=head1 NAME
Coro::AnyEvent - integrate threads into AnyEvent
=head1 SYNOPSIS
use Coro;
use AnyEvent;
# using both Coro and AnyEvent will automatically load Coro::AnyEvent
# or load it manually for its utility functions:
use Coro::AnyEvent;
Coro::AnyEvent::sleep 5; # block current thread for 5s
Coro::AnyEvent::poll; # poll for new events once
Coro::AnyEvent::idle; # block until process no longer busy
Coro::AnyEvent::idle_upto 5; # same, but only up to 5 seconds
Coro::AnyEvent::readable $fh, 60
or die "fh didn't become readable within 60 seconds\n";
=head1 DESCRIPTION
When one naively starts to use threads in Perl, one will quickly run
into the problem that threads which block on a syscall (sleeping,
reading from a socket etc.) will block all threads.
If one then uses an event loop, the problem is that the event loop has
no knowledge of threads and will not run them before it polls for new
events, again blocking the whole process.
This module integrates threads into any event loop supported by
AnyEvent, combining event-based programming with coroutine-based
programming in a natural way.
As of Coro 5.21 and newer, this module gets loaded automatically when
AnyEvent initialises itself and Coro is used in the same process, thus
there is no need to load it manually if you just want your threads to
coexist with AnyEvent.
If you want to use any functions from this module, you of course still
need to C<use Coro::AnyEvent>, just as with other perl modules.
Also, this module autodetects the event loop used (by relying on
L<AnyEvent>) and will either automatically defer to the high-performance
L<Coro::EV> or L<Coro::Event> modules, or will use a generic integration
method that should work with any event loop supported by L<AnyEvent>.
=head1 USAGE
=head2 RUN AN EVENT LOOP - OR NOT?
For performance reasons, it is recommended that the main program or
something else run the event loop of the event model you use, i.e.
use Gtk2; # <- the event model
use AnyEvent;
use Coro:
# initialise stuff
async { ... };
# now run mainloop of Gtk2
main Gtk2;
You can move the event loop into a thread as well, although this tends to
get confusing:
use Gtk2;
use AnyEvent;
use Coro:
async { main Gtk2 };
# do other things...
while () {
Coro/AnyEvent.pm view on Meta::CPAN
my $_poll = AnyEvent->can ("_poll")
|| AnyEvent->can ("one_event"); # AnyEvent < 6.0
while () {
$_poll->();
Coro::schedule if Coro::nready;
}
};
$IDLE->{desc} = "[AnyEvent idle process]";
$Coro::idle = $IDLE;
# call the readyhook, in case coroutines were already readied
_activity;
}
# augment condvars
unshift @AnyEvent::CondVar::ISA, "Coro::AnyEvent::CondVar";
};
=item Coro::AnyEvent::poll
This call will block the current thread until the event loop has polled
for potential new events and instructs the event loop to poll for new
events once, without blocking.
Note that this call will not actually execute the poll, nor will it wait
until there are some events, just block until the event loop has polled
for new events, so other threads will have a chance to run.
This is useful when you have a thread that does some computations, but you
still want to poll for new events from time to time. Simply call C<poll>
from time to time:
my $long_calc = async {
for (1..10000) {
Coro::AnyEvent::poll;
# do some stuff, make sure it takes at least 0.001s or so
}
}
Although you should also consider C<idle> or C<idle_upto> in such cases.
=item Coro::AnyEvent::sleep $seconds
This blocks the current thread for at least the given number of seconds.
=item Coro::AnyEvent::idle
This call is similar to C<poll> in that it will also poll for
events. Unlike C<poll>, it will only resume the thread once there are no
events to handle anymore, i.e. when the process is otherwise idle.
This is good for background threads that shouldn't use CPU time when
foreground jobs are ready to run.
=item Coro::AnyEvent::idle_upto $seconds
Like C<idle>, but with a maximum waiting time.
If your process is busy handling events, calling C<idle> can mean that
your thread will never be resumed. To avoid this, you can use C<idle_upto>
and specify a timeout, after which your thread will be resumed even if the
process is completely busy.
=item Coro::AnyEvent::readable $fh_or_fileno[, $timeout]
=item Coro::AnyEvent::writable $fh_or_fileno[, $timeout]
Blocks the current thread until the given file handle (or file descriptor)
becomes readable (or writable), or the given timeout has elapsed,
whichever happens first. No timeout counts as infinite timeout.
Returns true when the file handle became ready, false when a timeout
occurred.
Note that these functions are quite inefficient as compared to using a
single watcher (they recreate watchers on every invocation) or compared to
using Coro::Handle.
Note also that they only work for sources that have reasonable
non-blocking behaviour (e.g. not files).
Example: wait until STDIN becomes readable, then quit the program.
use Coro::AnyEvent;
print "press enter to quit...\n";
Coro::AnyEvent::readable *STDIN;
exit 0;
=cut
sub poll() {
my $w = AE::timer 0, 0, Coro::rouse_cb;
Coro::rouse_wait;
}
sub sleep($) {
my $w = AE::timer $_[0], 0, Coro::rouse_cb;
Coro::rouse_wait;
}
sub idle() {
my $w = AE::idle Coro::rouse_cb;
Coro::rouse_wait;
}
sub idle_upto($) {
my $cb = Coro::rouse_cb;
my $t = AE::timer shift, 0, $cb;
my $w = AE::idle $cb;
Coro::rouse_wait;
}
sub readable($;$) {
my $cb = Coro::rouse_cb;
my $w = AE::io $_[0], 0, sub { $cb->(1) };
my $t = defined $_[1] && AE::timer $_[1], 0, sub { $cb->(0) };
Coro::rouse_wait
}
sub writable($;$) {
my $cb = Coro::rouse_cb;
my $w = AE::io $_[0], 1, sub { $cb->(1) };
( run in 1.271 second using v1.01-cache-2.11-cpan-4ab04211f4c )