LINUX.ORG.RU

[libmicrohttpd] Отложенный ответ


0

1

Пришёл запрос. Вызывается MHD_AccessHandlerCallback. В документации пишут, что этот callback должен вызвать MHD функции для того чтобы ответить клиенту.

А если мы ответ читаем из файла, то придется ждать окончания операции чтения. А в это время могут приходить другие запросы. Это плохо.

Проверил экспериментально: если в MHD_AccessHandlerCallback не отвечать, а сохранить connection и начать не блокируемую операцию чтения из файла, то, дождавшись (epoll-ом или select-ом) её окончания (в другом потоке, конечно), можно ответить в сохранённый connection. В этом потоке можно ждать окончания нескольких операций чтения из файла. И для каждой отвечать в соответствующей ей connection.

Но при этом, каждую секунду будет вызываться MHD_AccessHandlerCallback для тех запросов на которые мы ждём окончания операций чтения.

Можно как-нибуть (в libmicrohttpd) отвечать не сразу (не в MHD_AccessHandlerCallback)?

Игнорирование обрабатываемых запросов (в MHD_AccessHandlerCallback) и использования отдельного потока для каждого запроса не предлагать. Можно предлагать альтернативные библиотеки (но только на чистом C).

Предложу Mongoose.

http://code.google.com/p/mongoose/

Тоже написан на чистом Си, работает по крайней мере под линуксом и оффтопиком, реализация в одном .c файле.

Реализует поточную модель, то есть, запускает thread pool из скольких скажешь тредов, и выбирает свободную нить для синхронного ответа на запрос. Вроде бы, не течет. Поддерживает ssl через libssl, POST, GET, Cookie, keep-alive соединения, cgi.

Что важно - не пытается быть умнее программиста, в том числе давал сделать HTTP 1.1 не по стандарту, а именно такой, какой мне требовалось, полный контроль за http - заголовками ( для того, чтобы кривой клиент без исходников мог хавать. )

anymouse
()
Ответ на: комментарий от anymouse

Спасибо, но thread pool противоречит моей религии.

Если мне никто не поможет, буду писать на nodejs. Да, я вам всем угрожаю.

LinuxUser ★★★
() автор топика

> А если мы ответ читаем из файла, то придется ждать окончания операции чтения. А в это время могут приходить другие запросы. Это плохо.

Что помешало использовать external select?

Внутри MHD_AccessHandlerCallback вызываем MHD_create_response_from_callback(), ему передаём функцию-callback (типа MHD_ContentReaderCallback). Если из callback вернуть 0, то при следующем вызове MHD_run() снова будет вызван этот callback.

Во внешнем цикле select ждём событий на всех дескрипторах сразу: и коннектов MHD, и файлов из которых читаем. Если событие относится к файлу, то вычитываем сколько удастся в буфер привязанный к контексту соединения + выставляем флаг для callback. Затем вызываем MHD_run(), который дёргает наш callback.

Вроле должно работать, как надо, разве нет? Zero-copy правда не получится.

Vond ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.