Client abort detection w/ upstream broken on anything but kqueue ()?
Maxim Dounin
mdounin at mdounin.ru
Wed Nov 3 03:11:57 MSK 2010
Hello!
On Tue, Nov 02, 2010 at 10:14:34PM +0100, Marcello Barnaba wrote:
> Hello,
>
> I'm investigating why client aborts are successfully detected
> by nginx when using kqueue () on BSD systems and not when using
> poll () on BSD & Linux or epoll () on Linux systems.
>
> I've done debug sessions and I nailed down the problem to the
> ngx_http_upstream_check_broken_connection function, line 917 of
> http/ngx_http_upstream.c of release 0.8.53.
>
> From my tests on a Darwin 10.4.0 using poll () and on a Linux
> 2.6.32 using epoll () a client that closes its socket makes the
> recv () on line 994 return 1, with errno set to EWOULDBLOCK on
> Darwin/poll () and to EAGAIN on Linux/epoll ().
Looking into errno without getting error from function is
meaningless[1].
[1] http://www.opengroup.org/onlinepubs/9699919799/functions/errno.html
>
> I've tried to change the condition at line 1016 from n > 0 to
> (n > 0 && err != NGX_EAGAIN && err != NGX_EWOULDBLOCK) but I'm
> sure it doesn't make much sense.
>
> Is this a known issue? From where should I start to solve it?
As long as recv() returned 1 - it means that you have outstanding
data in connection (e.g. some pipelined request) and it's
impossible to detect if connection was closed or not without
reading this data or writing something to connection (or some
out-of-band hint from OS as kqueue provides).
At the point in question it's not possible to read all data or
write something, so basically premature connection close by client
with outstanding data is undetectable with classic socket
interface.
This shouldn't be a major issue though:
a) normally connections doesn't have outstanding data when user
cancels request (closes browser window, hits "stop" and so on) and
the detection works well even without kqueue;
b) this is only optimization anyway.
Maxim Dounin
More information about the nginx
mailing list