[dev] synchronous write

Igor Sysoev is at rambler-co.ru
Tue Oct 23 11:19:03 MSD 2007


On Tue, Oct 23, 2007 at 11:10:37AM +0400, Igor Sysoev wrote:

> On Mon, Oct 22, 2007 at 09:42:07PM +0200, Manlio Perillo wrote:
> 
> > Igor Sysoev ha scritto:
> > >On Mon, Oct 22, 2007 at 01:11:21PM +0200, Manlio Perillo wrote:
> > >
> > >>Igor Sysoev ha scritto:
> > >>>[...]
> > >>>>>No, this completely kill the idea of nginx - a worker will be blocked.
> > >>>>>
> > >>>>Unfortunately this is required by the WSGI spec, and some "legacy" WSGI 
> > >>>>applications will block the worker, anyway.
> > >>>>
> > >>>>I have implemented an alternative version that uses a buffer, but I 
> > >>>>would like to know if using this "hack" is "safe", that is if Nginx 
> > >>>>will send the correct data to the client and if after setting again the 
> > >>>>socket to nonblocking mode, Nginx will work as usual.
> > >>>Yes, it will work. However, you should use the following cycle:
> > >>>
> > >>>   ngx_blocking(self->r->connection->fd);
> > >>>
> > >>>   do {
> > >>>       rc = ngx_http_output_filter(self->r, &out);
> > >>>   } while (rc == NGX_AGAIN);
> > >>>
> > >>>   ngx_nonblocking(self->r->connection->fd);
> > >>>
> > >>That's unexpected, I have assumed that with socket in blocking mode 
> > >>ngx_http_output_filter never returns NGX_AGAIN.
> > >
> > >No, write() to a socket in blocking mode may send less bytes than you ask.
> > >
> > 
> > But NGX_AGAIN is returned also for EINTR?
> 
> No, nginx handles EINTR in write/sendfile opertaion and does not return
> NGX_AGAIN.
> 
> > I have noted that when testing your "patch" over a slow connection 
> > (qemu) and with a very big buffer, hitting Ctrl-C cause an infinite(?) loop.
> 
> Could you show debug log of this loop ?

The loop should be:

    do {
       rc = ngx_http_output_filter(self->r, &out);

       self->r->connection->write->ready = 1;

    } while (rc == NGX_AGAIN);

In usual processing event->ready is set by event module (kqueue/epoll/etc).

> > P.S.: even with a very big buffer, ngx_http_output_filter never returns
> >       NGX_AGAIN
> 
> Probably because kernel TCP buffer is big enough.
> 
> 
> -- 
> Igor Sysoev
> http://sysoev.ru/en/
> 

-- 
Igor Sysoev
http://sysoev.ru/en/





More information about the nginx mailing list