Повторные попытки должны делаться позднее. Верхние уровни должны
корректно обрабатывать wev->ready == 0 и возрат != NULL из функции..
В том то и дело, что повторные попытки не делаются даже позднее,
просто выходит и все. Прошу проверить.
----- Original Message -----
From: "Igor Sysoev" <is@xxxxxxxxxxxxx>
To: <nginx-ru@xxxxxxxxx>
Sent: Friday, July 06, 2007 1:16 PM
Subject: Re: Баг или фича?
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 из функции..