Баг или фича?

Igor Sysoev is at rambler-co.ru
Fri Jul 6 13:16:35 MSD 2007


On Fri, Jul 06, 2007 at 12:59:10PM +0400, Denis Erygin wrote:

> Под FreeBSD обнаружил проблему с обрезанием страниц больших 32 Кб,
> под Linux больших 12 КБ, который отдаются в chain-ах из памяти 
> (без in_file = 1, т.е. без использования временных файлов, через writev).
> 
> Расследование привело к условию ниже:
> 
> src/os/unix/ngx_freebsd_sendfile_chain.c:399
> src/os/unix/ngx_linux_sendfile_chain.c:360
> 
> if (!complete) {
>    wev->ready = 0;
>    return cl;
> }
> 
> Если закомментировать этот блок/условие, то страницы отдаются полностью,
> но появляется много записей в логах типа этой:
> 
> writev() not ready (11: Resource temporarily unavailable)
> 
> Какой смысл несет условие выше, и как можно решить эту проблему 
> более прямым способом? Неужели нельзя вернуться и продолжить запись?

Нет, нельзя - нужно подождать, когда ядро сообщит о свободном месте.
А в это время можно или обрабатывать другие соединения, или же вообще
ничего не делать, ожидая в kevent/epoll/etc.

Если же это условие убрать, то nginx будет бессмысленно крутиться
в цикле, кушая процессор.

> Насколькоя понял, writev гарантировано успевает передать заголовки,
> затем пытается передать тело, но передает только сколько влезет в системный буфер,
> затем происходит выход по if (!complete) ,  после чего повторных попыток 
> продолжения записи не происходит.

Повторные попытки должны делаться позднее. Верхние уровни должны
корректно обрабатывать wev->ready == 0 и возрат != NULL из функции.

> И это на всех версиях nginx.


-- 
Игорь Сысоев
http://sysoev.ru





More information about the nginx-ru mailing list