Author: stas Date: Thu Apr 28 15:16:18 2005 New Revision: 165212 URL: http://svn.apache.org/viewcvs?rev=165212&view=rev Log: sock->recv may trigger both: is_EAGAIN and TIMEUP error: nonblocking IO => is_EAGAIN timeout(0) => is_EAGAIN timeout(1) => TIMEUP so update the docs to include both
Modified: perl/modperl/docs/trunk/src/docs/2.0/api/APR/Error.pod perl/modperl/docs/trunk/src/docs/2.0/api/APR/Socket.pod Modified: perl/modperl/docs/trunk/src/docs/2.0/api/APR/Error.pod URL: http://svn.apache.org/viewcvs/perl/modperl/docs/trunk/src/docs/2.0/api/APR/Error.pod?rev=165212&r1=165211&r2=165212&view=diff ============================================================================== --- perl/modperl/docs/trunk/src/docs/2.0/api/APR/Error.pod (original) +++ perl/modperl/docs/trunk/src/docs/2.0/api/APR/Error.pod Thu Apr 28 15:16:18 2005 @@ -88,12 +88,16 @@ There are two ways to figure out whether an error fits your case. In most cases you just compare C<$@> with an the error constant. For -example: +example if a socket has a timeout set and the data wasn't read within +the timeout limit a +C<L<APR::Const::TIMEUP|docs::2.0::api::APR::Const/C_APR__Const__TIMEUP_>>) use APR::Const -compile => qw(TIMEUP); - # some code throwing an exception + $sock->timeout_set(1_000_000); # 1 sec + my $buff; + eval { $socket->recv($buff, BUFF_LEN) }; if ($@ && ref $@ && $@ == APR::Const::TIMEUP) { - # do something + } However there are situations, where on different Operating Systems a @@ -102,7 +106,9 @@ C<L<APR::Status|docs::2.0::api::APR::Status>> class. One such condition is socket C<recv()> timeout, which on Unix throws the C<EAGAIN> error, but on other system it throws a different error. In -this case L<APR::Status::is_EAGAIN> should be used. +this case +C<L<APR::Status::is_EAGAIN|docs::2.0::api::APR::Status/C_is_EAGAIN_>> +should be used. Let's look at a complete example. Here is a code that performs L<a socket read|docs::2.0::api::APR::Socket/C_recv_>: Modified: perl/modperl/docs/trunk/src/docs/2.0/api/APR/Socket.pod URL: http://svn.apache.org/viewcvs/perl/modperl/docs/trunk/src/docs/2.0/api/APR/Socket.pod?rev=165212&r1=165211&r2=165212&view=diff ============================================================================== --- perl/modperl/docs/trunk/src/docs/2.0/api/APR/Socket.pod (original) +++ perl/modperl/docs/trunk/src/docs/2.0/api/APR/Socket.pod Thu Apr 28 15:16:18 2005 @@ -263,15 +263,43 @@ If you get the C<'(11) Resource temporarily unavailable'> error (exception -C<L<APR::Const::EAGAIN|docs::2.0::api::APR::Const/C_APR__EAGAIN_>>), then you -didn't ensure that the socket is in L<a blocking IO mode|/C_opt_set_> -before using it. +C<L<APR::Const::EAGAIN|docs::2.0::api::APR::Const/C_APR__EAGAIN_>>) +(or another equivalent, which might be different on non-POSIX +systems), then you didn't ensure that the socket is in L<a blocking IO +mode|/C_opt_set_> before using it. Note that you should use +C<L<APR::Status::is_EAGAIN|docs::2.0::api::APR::Status/C_is_EAGAIN_>> +to perform this check (since different error codes may be returned for +the same event on different OSes). For example if the socket is set to +the non-blocking mode and there is no data right away, you may get +this exception thrown. So here is how to check for it and retry a few +times after short delays: + + use APR::Status (); + $sock->opt_set(APR::Const::SO_NONBLOCK, 1); + # .... + my $tries = 0; + RETRY: my $rlen = eval { $socket->recv(my $buffer, SIZE) }; + if ($@) + die $@ unless ref $@ && APR::Status::is_EAGAIN($@); + if ($tries++ < 3) { + # sleep 250msec + select undef, undef, undef, 0.25; + goto RETRY; + } + else { + # do something else + } + } + warn "read $rlen bytes\n" + If timeout was set via C<timeout_set|/C_timeout_set_>, you may need to -catch the C<L<APR::Const::TIMEUP|docs::2.0::api::APR::Const/C_APR__TIMEUP_>> +catch the +C<L<APR::Const::TIMEUP|docs::2.0::api::APR::Const/C_APR__TIMEUP_>> exception. For example: use APR::Const -compile => qw(TIMEUP); + $sock->timeout_set(1_000_000); # 1 sec my $buffer; eval { $sock->recv($buffer, $wanted) }; if ($@ && $@ == APR::Const::TIMEUP) { --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]