--- AnyEvent/lib/AnyEvent.pm 2008/07/02 12:27:42 1.161 +++ AnyEvent/lib/AnyEvent.pm 2008/07/08 23:44:51 1.167 @@ -154,11 +154,11 @@ You can create an I/O watcher by calling the C<< AnyEvent->io >> method with the following mandatory key-value pairs as arguments: -C the Perl I (I file descriptor) to watch -for events. C must be a string that is either C or C, -which creates a watcher waiting for "r"eadable or "w"ritable events, -respectively. C is the callback to invoke each time the file handle -becomes ready. +C the Perl I (I file descriptor) to watch for events +(AnyEvent might or might not keep a reference to this file handle). C +must be a string that is either C or C, which creates a watcher +waiting for "r"eadable or "w"ritable events, respectively. C is the +callback to invoke each time the file handle becomes ready. Although the callback might get passed parameters, their value and presence is undefined and you cannot rely on them. Portable AnyEvent @@ -172,9 +172,9 @@ always use non-blocking calls when reading/writing from/to your file handles. -Example: +Example: wait for readability of STDIN, then read a line and disable the +watcher. - # wait for readability of STDIN, then read a line and disable the watcher my $w; $w = AnyEvent->io (fh => \*STDIN, poll => 'r', cb => sub { chomp (my $input = ); warn "read: $input\n"; @@ -194,13 +194,18 @@ presence is undefined and you cannot rely on them. Portable AnyEvent callbacks cannot use arguments passed to time watcher callbacks. -The timer callback will be invoked at most once: if you want a repeating -timer you have to create a new watcher (this is a limitation by both Tk -and Glib). +The callback will normally be invoked once only. If you specify another +parameter, C, as a strictly positive number (> 0), then the +callback will be invoked regularly at that interval (in fractional +seconds) after the first invocation. If C is specified with a +false value, then it is treated as if it were missing. + +The callback will be rescheduled before invoking the callback, but no +attempt is done to avoid timer drift in most backends, so the interval is +only approximate. -Example: +Example: fire an event after 7.7 seconds. - # fire an event after 7.7 seconds my $w = AnyEvent->timer (after => 7.7, cb => sub { warn "timeout\n"; }); @@ -208,19 +213,12 @@ # to cancel the timer: undef $w; -Example 2: +Example 2: fire an event after 0.5 seconds, then roughly every second. - # fire an event after 0.5 seconds, then roughly every second - my $w; - - my $cb = sub { - # cancel the old timer while creating a new one - $w = AnyEvent->timer (after => 1, cb => $cb); + my $w = AnyEvent->timer (after => 0.5, interval => 1, cb => sub { + warn "timeout\n"; }; - # start the "loop" by creating the first watcher - $w = AnyEvent->timer (after => 0.5, cb => $cb); - =head3 TIMING ISSUES There are two ways to handle timers: based on real time (relative, "fire @@ -307,8 +305,8 @@ =head2 SIGNAL WATCHERS You can watch for signals using a signal watcher, C is the signal -I without any C prefix, C is the Perl callback to -be invoked whenever a signal occurs. +I in uppercase and without any C prefix, C is the Perl +callback to be invoked whenever a signal occurs. Although the callback might get passed parameters, their value and presence is undefined and you cannot rely on them. Portable AnyEvent @@ -740,16 +738,18 @@ Contains various utility functions that replace often-used but blocking functions such as C by event-/callback-based versions. -=item L - -Provide read and write buffers and manages watchers for reads and writes. - =item L Provides various utility functions for (internet protocol) sockets, addresses and name resolution. Also functions to create non-blocking tcp connections or tcp servers, with IPv6 and SRV record support and more. +=item L + +Provide read and write buffers, manages watchers for reads and writes, +supports raw and formatted I/O, I/O queued and fully transparent and +non-blocking SSL/TLS. + =item L Provides rich asynchronous DNS resolver capabilities. @@ -769,7 +769,27 @@ =item L -Executes DBI requests asynchronously in a proxy process. +Executes L requests asynchronously in a proxy process. + +=item L + +Truly asynchronous I/O, should be in the toolbox of every event +programmer. AnyEvent::AIO transparently fuses L and AnyEvent +together. + +=item L + +Truly asynchronous Berkeley DB access. AnyEvent::BDB transparently fuses +L and AnyEvent together. + +=item L + +A non-blocking interface to gpsd, a daemon delivering GPS information. + +=item L + +A non-blocking interface to the Internet Go Server protocol (used by +L). =item L @@ -792,17 +812,6 @@ Has special support for AnyEvent via L. -=item L, L - -Truly asynchronous I/O, should be in the toolbox of every event -programmer. AnyEvent::AIO transparently fuses IO::AIO and AnyEvent -together. - -=item L, L - -Truly asynchronous Berkeley DB access. AnyEvent::AIO transparently fuses -IO::AIO and AnyEvent together. - =item L The lambda approach to I/O - don't ask, look there. Can use AnyEvent. @@ -818,7 +827,7 @@ use Carp; -our $VERSION = '4.160'; # temporary workaround for broken fedora +our $VERSION = 4.2; our $MODEL; our $AUTOLOAD; @@ -931,9 +940,15 @@ } } - unshift @ISA, $MODEL; push @{"$MODEL\::ISA"}, "AnyEvent::Base"; + if ($ENV{PERL_ANYEVENT_STRICT}) { + unshift @AnyEvent::Base::Strict::ISA, $MODEL; + unshift @ISA, AnyEvent::Base::Strict:: + } else { + unshift @ISA, $MODEL; + } + (shift @post_detect)->() while @post_detect; } @@ -1108,6 +1123,124 @@ *broadcast = \&send; *wait = \&_wait; +package AnyEvent::Base::Strict; + +use Carp qw(croak); + +# supply checks for argument validity for many functions + +sub io { + my $class = shift; + my %arg = @_; + + ref $arg{cb} + or croak "AnyEvent->io called with illegal cb argument '$arg{cb}'"; + delete $arg{cb}; + + fileno $arg{fh} + or croak "AnyEvent->io called with illegal fh argument '$arg{fh}'"; + delete $arg{fh}; + + $arg{poll} =~ /^[rw]$/ + or croak "AnyEvent->io called with illegal poll argument '$arg{poll}'"; + delete $arg{poll}; + + croak "AnyEvent->io called with unsupported parameter(s) " . join ", ", keys %arg + if keys %arg; + + $class->SUPER::io (@_) +} + +sub timer { + my $class = shift; + my %arg = @_; + + ref $arg{cb} + or croak "AnyEvent->timer called with illegal cb argument '$arg{cb}'"; + delete $arg{cb}; + + exists $arg{after} + or croak "AnyEvent->timer called without mandatory 'after' parameter"; + delete $arg{after}; + + $arg{interval} > 0 || !$arg{interval} + or croak "AnyEvent->timer called with illegal interval argument '$arg{interval}'"; + delete $arg{interval}; + + croak "AnyEvent->timer called with unsupported parameter(s) " . join ", ", keys %arg + if keys %arg; + + $class->SUPER::timer (@_) +} + +sub signal { + my $class = shift; + my %arg = @_; + + ref $arg{cb} + or croak "AnyEvent->signal called with illegal cb argument '$arg{cb}'"; + delete $arg{cb}; + + eval "require POSIX; defined &POSIX::SIG$arg{signal}" + or croak "AnyEvent->signal called with illegal signal name '$arg{signal}'"; + delete $arg{signal}; + + croak "AnyEvent->signal called with unsupported parameter(s) " . join ", ", keys %arg + if keys %arg; + + $class->SUPER::signal (@_) +} + +sub child { + my $class = shift; + my %arg = @_; + + ref $arg{cb} + or croak "AnyEvent->signal called with illegal cb argument '$arg{cb}'"; + delete $arg{cb}; + + $arg{pid} =~ /^-?\d+$/ + or croak "AnyEvent->signal called with illegal pid value '$arg{pid}'"; + delete $arg{pid}; + + croak "AnyEvent->signal called with unsupported parameter(s) " . join ", ", keys %arg + if keys %arg; + + $class->SUPER::child (@_) +} + +sub condvar { + my $class = shift; + my %arg = @_; + + !exists $arg{cb} or ref $arg{cb} + or croak "AnyEvent->condvar called with illegal cb argument '$arg{cb}'"; + delete $arg{cb}; + + croak "AnyEvent->condvar called with unsupported parameter(s) " . join ", ", keys %arg + if keys %arg; + + $class->SUPER::condvar (@_) +} + +sub time { + my $class = shift; + + @_ + and croak "AnyEvent->time wrongly called with paramaters"; + + $class->SUPER::time (@_) +} + +sub now { + my $class = shift; + + @_ + and croak "AnyEvent->now wrongly called with paramaters"; + + $class->SUPER::now (@_) +} + =head1 SUPPLYING YOUR OWN EVENT MODEL INTERFACE This is an advanced topic that you do not normally need to use AnyEvent in @@ -1170,6 +1303,15 @@ When set to C<2> or higher, cause AnyEvent to report to STDERR which event model it chooses. +=item C + +AnyEvent does not do much argument checking by default, as thorough +argument checking is very costly. Setting this variable to a true value +will cause AnyEvent to thoroughly check the arguments passed to most +method calls and croaks if it finds any problems. In other words, enables +"strict" mode. Unlike C it is definitely recommended ot keep +it off in production. + =item C This can be used to specify the event model to be used by AnyEvent, before @@ -1675,7 +1817,8 @@ Similar considerations apply to $ENV{PERL_ANYEVENT_VERBOSE}, as that can be used to probe what backend is used and gain other information (which is -probably even less useful to an attacker than PERL_ANYEVENT_MODEL). +probably even less useful to an attacker than PERL_ANYEVENT_MODEL), and +$ENV{PERL_ANYEGENT_STRICT}. =head1 BUGS