Every call to C<< ->begin >> will increment a counter, and every call to
C<< ->end >> will decrement it. If the counter reaches C<0> in C<< ->end
>>, the (last) callback passed to C<begin> will be executed. That callback
is I<supposed> to call C<< ->send >>, but that is not required. If no
callback was set, C<send> will be called without any arguments.
Let's clarify this with the ping example:
my $cv = AnyEvent->condvar;
my %result;
$cv->begin (sub { $cv->send (\%result) });
for my $host (@list_of_hosts) {
$cv->begin;
ping_host_then_call_callback $host, sub {
$result{$host} = ...;
$cv->end;
};
}
$cv->end;
This code fragment supposedly pings a number of hosts and calls
C<send> after results for all then have have been gathered - in any
order. To achieve this, the code issues a call to C<begin> when it starts
each ping request and calls C<end> when it has received some result for
it. Since C<begin> and C<end> only maintain a counter, the order in which
results arrive is not relevant.
There is an additional bracketing call to C<begin> and C<end> outside the
loop, which serves two important purposes: first, it sets the callback
to be called once the counter reaches C<0>, and second, it ensures that
C<send> is called even when C<no> hosts are being pinged (the loop
doesn't execute once).
This is the general pattern when you "fan out" into multiple subrequests:
use an outer C<begin>/C<end> pair to set the callback and ensure C<end>
is called at least once, and then, for each subrequest you start, call
C<begin> and for each subrequest you finish, call C<end>.
=back
=head3 METHODS FOR CONSUMERS
These methods should only be used by the consuming side, i.e. the
code awaits the condition.
=over 4
=item $cv->recv
Wait (blocking if necessary) until the C<< ->send >> or C<< ->croak
>> methods have been called on c<$cv>, while servicing other watchers
normally.
You can only wait once on a condition - additional calls are valid but
will return immediately.
If an error condition has been set by calling C<< ->croak >>, then this
function will call C<croak>.
In list context, all parameters passed to C<send> will be returned,
in scalar context only the first one will be returned.
Not all event models support a blocking wait - some die in that case
(programs might want to do that to stay interactive), so I<if you are
using this from a module, never require a blocking wait>, but let the
caller decide whether the call will block or not (for example, by coupling
condition variables with some kind of request results and supporting
callbacks so the caller knows that getting the result will not block,
while still supporting blocking waits if the caller so desires).
Another reason I<never> to C<< ->recv >> in a module is that you cannot
sensibly have two C<< ->recv >>'s in parallel, as that would require
multiple interpreters or coroutines/threads, none of which C<AnyEvent>
can supply.
The L<Coro> module, however, I<can> and I<does> supply coroutines and, in
fact, L<Coro::AnyEvent> replaces AnyEvent's condvars by coroutine-safe
versions and also integrates coroutines into AnyEvent, making blocking
C<< ->recv >> calls perfectly safe as long as they are done from another
coroutine (one that doesn't run the event loop).
You can ensure that C<< -recv >> never blocks by setting a callback and
only calling C<< ->recv >> from within that callback (or at a later
time). This will work even when the event loop does not support blocking
waits otherwise.
=item $bool = $cv->ready
Returns true when the condition is "true", i.e. whether C<send> or
C<croak> have been called.
=item $cb = $cv->cb ([new callback])
This is a mutator function that returns the callback set and optionally
replaces it before doing so.
=6= |