You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Joe Orton <jo...@redhat.com> on 2012/08/13 14:32:21 UTC
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)
Hmmmm, 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?
Regards, Joe
RE: core filters vs non-blocking socket (was Re: Fix for Windows
bug#52476)
Posted by Plüm,
Rüdiger,
Vodafone Group <ru...@vodafone.com>.
> -----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
> <ru...@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)
Posted by Jeff Trawick <tr...@gmail.com>.
On Mon, Aug 13, 2012 at 9:31 AM, Plüm, Rüdiger, Vodafone Group
<ru...@vodafone.com> wrote:
>
>
>> -----Original Message-----
>> From: Joe Orton [mailto:jorton@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)
>>
>> Hmmmm, 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)
Posted by Plüm,
Rüdiger,
Vodafone Group <ru...@vodafone.com>.
> -----Original Message-----
> From: Joe Orton [mailto:jorton@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)
>
> Hmmmm, 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)
Posted by Joe Orton <jo...@redhat.com>.
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
Re: core filters vs non-blocking socket (was Re: Fix for Windows bug#52476)
Posted by Jeff Trawick <tr...@gmail.com>.
On Mon, Aug 13, 2012 at 8:32 AM, Joe Orton <jo...@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)
>
> Hmmmm, 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 60000000 (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 (60000000)
* also called from SSL flush, writev_nonblocking() sets timeout to 0
and then restores the timeout (60000000)
* in some complicated flow from default_handler through SSL,
writev_nonblocking sets timeout to 0 then restores the timeout
* lingering_close() sets timeout to 2000000
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/