Re: core filters vs non-blocking socket (was Re: Fix for Windows bug#52476)
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)
-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)
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)
-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)
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