Re: core filters vs non-blocking socket (was Re: Fix for Windows bug#52476)

2012-08-13 Thread Jeff Trawick
On Mon, Aug 13, 2012 at 8:32 AM, Joe Orton jor...@redhat.com wrote:
 On Fri, Aug 10, 2012 at 01:31:07PM -0400, Jeff Trawick wrote:
 We picked up that apr_socket_opt_set() from the async-dev branch with
 r327872, though the timeout calls in there were changed subsequently.
 I wonder if that call is stray and it doesn't get along with the
 timeout handling on Windows because of the SO_RCVTIMEO/SO_SENDTIMEO
 use on Windows, in lieu of non-blocking socket + poll like on Unix.

 At the time it was added, the new code was

 apr_socket_timeout_set(client_socket, 0)
 apr_socket_opt_set(client_socket, APR_SO_NONBLOCK, 1)

 (redundant unless there was some APR glitch at the time)

 H, is this right?

 For event, the listening socket, and hence the accepted socket, is
 always set to non-blocking in the MPM.

 For non-event on Unix, the listening socket, and hence the accepted
 socket, is set to non-blocking IFF there are multiple listeners.

But the underlying descriptor for the accepted gets set to
non-blocking soon after accept() (see below).


 So that line is not redundant in the non-event, single listener
 configuration on Unix... no?

 Regards, Joe

Background:  With the APR socket implementation on Unix, the
underlying socket descriptor is placed in non-blocking mode when the
application (httpd) sets a timeout = 0.

For a single listener worker configuration with mod_reqtimeout
disabled and the default Timeout of 60 seconds, here's what happens
w.r.t. blocking and timeouts on the connected sockets once
core_create_conn() is entered.  This is with the bug present (i.e.,
with the needless apr_socket_opt_set()).  At the time
core_create_conn() is entered, the apr_socket_t has timeout -1 and the
only option set is APR_TCP_NODELAY).

* core_pre_connection() sets timeout to 6000  (this makes the
underlying socket non-blocking on Unix)
* SSL needs to read but first calls flush and ap_core_output_filter()
makes the APR socket non-blocking (bug according to me ;) )
* also called from SSL flush, writev_nonblocking() sets timeout to 0
(that also ensures that the underlying socket is non-blocking)
* writev_nonblocking() restores the timeout (6000)
* also called from SSL flush, writev_nonblocking() sets timeout to 0
and then restores the timeout (6000)
* in some complicated flow from default_handler through SSL,
writev_nonblocking sets timeout to 0 then restores the timeout
* lingering_close() sets timeout to 200

So the underlying socket descriptor is still made non-blocking on Unix
even before the bug is encountered, as part of the timeout
implementation.  And that call to mark the socket non-blocking with
apr_socket_opt_set() is out of sync with the rest of the code that
sets timeout to 0 or 0 as necessary.  (And of course it is out of
sync in a way that exposes the difference on Windows.)

Does that explanation work for you?

-- 
Born in Roswell... married an alien...
http://emptyhammock.com/


RE: core filters vs non-blocking socket (was Re: Fix for Windows bug#52476)

2012-08-13 Thread Plüm , Rüdiger , Vodafone Group


 -Original Message-
 From: Joe Orton [mailto:jor...@redhat.com]
 Sent: Montag, 13. August 2012 14:32
 To: dev@httpd.apache.org
 Subject: core filters vs non-blocking socket (was Re: Fix for Windows
 bug#52476)
 
 On Fri, Aug 10, 2012 at 01:31:07PM -0400, Jeff Trawick wrote:
  We picked up that apr_socket_opt_set() from the async-dev branch with
  r327872, though the timeout calls in there were changed subsequently.
  I wonder if that call is stray and it doesn't get along with the
  timeout handling on Windows because of the SO_RCVTIMEO/SO_SENDTIMEO
  use on Windows, in lieu of non-blocking socket + poll like on Unix.
 
  At the time it was added, the new code was
 
  apr_socket_timeout_set(client_socket, 0)
  apr_socket_opt_set(client_socket, APR_SO_NONBLOCK, 1)
 
  (redundant unless there was some APR glitch at the time)
 
 H, is this right?
 
 For event, the listening socket, and hence the accepted socket, is
 always set to non-blocking in the MPM.
 
 For non-event on Unix, the listening socket, and hence the accepted
 socket, is set to non-blocking IFF there are multiple listeners.
 
 So that line is not redundant in the non-event, single listener
 configuration on Unix... no?

Don't we switch to non-blocking in apr_socket_timeout_set if we set the timeout 
to 0?
And if we do a read with a timeout don't we do a poll with a timeout where it 
does not
matter whether the socket is blocking or non blocking?

Or did I get confused now completely?

Regards

Rüdiger



Re: core filters vs non-blocking socket (was Re: Fix for Windows bug#52476)

2012-08-13 Thread Jeff Trawick
On Mon, Aug 13, 2012 at 9:31 AM, Plüm, Rüdiger, Vodafone Group
ruediger.pl...@vodafone.com wrote:


 -Original Message-
 From: Joe Orton [mailto:jor...@redhat.com]
 Sent: Montag, 13. August 2012 14:32
 To: dev@httpd.apache.org
 Subject: core filters vs non-blocking socket (was Re: Fix for Windows
 bug#52476)

 On Fri, Aug 10, 2012 at 01:31:07PM -0400, Jeff Trawick wrote:
  We picked up that apr_socket_opt_set() from the async-dev branch with
  r327872, though the timeout calls in there were changed subsequently.
  I wonder if that call is stray and it doesn't get along with the
  timeout handling on Windows because of the SO_RCVTIMEO/SO_SENDTIMEO
  use on Windows, in lieu of non-blocking socket + poll like on Unix.
 
  At the time it was added, the new code was
 
  apr_socket_timeout_set(client_socket, 0)
  apr_socket_opt_set(client_socket, APR_SO_NONBLOCK, 1)
 
  (redundant unless there was some APR glitch at the time)

 H, is this right?

 For event, the listening socket, and hence the accepted socket, is
 always set to non-blocking in the MPM.

 For non-event on Unix, the listening socket, and hence the accepted
 socket, is set to non-blocking IFF there are multiple listeners.

 So that line is not redundant in the non-event, single listener
 configuration on Unix... no?

 Don't we switch to non-blocking in apr_socket_timeout_set if we set the 
 timeout to 0?

yes

apr_status_t apr_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
{
apr_status_t stat;

/* If our new timeout is non-negative and our old timeout was
 * negative, then we need to ensure that we are non-blocking.
 * Conversely, if our new timeout is negative and we had
 * non-negative timeout, we must make sure our socket is blocking.
 * We want to avoid calling fcntl more than necessary on the
 * socket.
 */
if (t = 0  sock-timeout  0) {
if (apr_is_option_set(sock, APR_SO_NONBLOCK) != 1) {
if ((stat = sononblock(sock-socketdes)) != APR_SUCCESS) {
return stat;
}
apr_set_option(sock, APR_SO_NONBLOCK, 1);
}
}
else if (t  0  sock-timeout = 0) {
if (apr_is_option_set(sock, APR_SO_NONBLOCK) != 0) {
if ((stat = soblock(sock-socketdes)) != APR_SUCCESS) {
return stat;
}
apr_set_option(sock, APR_SO_NONBLOCK, 0);
}
}
   ...

 And if we do a read with a timeout don't we do a poll with a timeout where it 
 does not
 matter whether the socket is blocking or non blocking?

from a high-level, yes; but there is some logic in APR to guess when
data is already available to read, and that requires that the socket
is non-blocking in case the guess is incorrect (that logic is
associated with the APR_INCOMPLETE_READ flag)


 Or did I get confused now completely?

no


 Regards

 Rüdiger




-- 
Born in Roswell... married an alien...
http://emptyhammock.com/


RE: core filters vs non-blocking socket (was Re: Fix for Windows bug#52476)

2012-08-13 Thread Plüm , Rüdiger , Vodafone Group


 -Original Message-
 From: Jeff Trawick [mailto:]
 Sent: Montag, 13. August 2012 15:35
 To: dev@httpd.apache.org
 Subject: Re: core filters vs non-blocking socket (was Re: Fix for
 Windows bug#52476)
 
 On Mon, Aug 13, 2012 at 9:31 AM, Plüm, Rüdiger, Vodafone Group
 ruediger.pl...@vodafone.com wrote:
 
  And if we do a read with a timeout don't we do a poll with a timeout
 where it does not
  matter whether the socket is blocking or non blocking?
 
 from a high-level, yes; but there is some logic in APR to guess when
 data is already available to read, and that requires that the socket
 is non-blocking in case the guess is incorrect (that logic is
 associated with the APR_INCOMPLETE_READ flag)

Thanks for the detailed clarification.

Regards

Rüdiger




Re: core filters vs non-blocking socket (was Re: Fix for Windows bug#52476)

2012-08-13 Thread Joe Orton
On Mon, Aug 13, 2012 at 09:27:08AM -0400, Jeff Trawick wrote:
 Does that explanation work for you?

Yes, perfectly, thanks for taking the time.  I stupidly forgot about the 
timeout calls... sorry!

Regards, Joe