|
From: | silvioprog |
Subject: | Re: [libmicrohttpd] MHD_quiesce_daemon() question |
Date: | Tue, 28 Mar 2017 00:05:46 -0300 |
And while Evgeny is 100% correct, let me point out the opposite concern:On 03/26/2017 10:36 PM, Evgeny Grin wrote:
> On 26.03.2017 8:33, silvioprog wrote:
>> I found the following related message:
>>
>> https://lists.gnu.org/archive/html/libmicrohttpd/2014-09/ msg00012.html
>>
>> I've used a similar logic, but with item X below, because I need to wait
>> the client processing:
>>
>> 1) MHD_quiesce_daemon()
>> *X) while (info.num_connections > 0) sleep(0.5s) # pseudo code*
>> 2) MHD_stop_daemon()
>> 3) close()
>>
>> Real implementation:
>>
>> bool bf_httpsrv_shutdown(struct bf_httpsrv *srv, bool force) {
>> MHD_socket fd;
>> if (srv && srv->listening) {
>> fd = MHD_quiesce_daemon(srv->mhd);
>> if (!force)
>> while (MHD_get_daemon_info(srv->mhd, MHD_DAEMON_INFO_CURRENT_CONNECTIONS)->num_connections > 0)
>> usleep(1000 * 500); //TODO: allow to use external callback
>> MHD_stop_daemon(srv->mhd);
>> if (fd != MHD_INVALID_SOCKET)
>> close(fd);
>> srv->listening = false;
>> return true;
>> }
>> return false;
>> }
>>
>>
>> Calling it with bf_httpsrv_shutdown(srv, false) the server stops waiting
>> for clients processing.
>>
>> So, what do you think about the logic above? Should it be improved?!
>>
>> Thanks in advance for any suggestions!
>
> If you don't check returned value from MHD_quiesce_daemon(), you may
> later found that you didn't quiesced daemon, so move check right after
> MHD_quiesce_daemon() and added error handling.
> If you didn't set connection timeout, connection may live indefinitely.
> Moreover, even with connection timeout, clients may continue processing
> on same HTTP 1.1 connections with new requests indefinitely.
> Furthermore, even with HTTP 1.0 and connection timeout hypothetical
> client may read answer very slow with results in very long unpredictable
> closure of connection.
> So: yes, you code will work but may result in very long (hours, for
> example) or even indefinitely long daemon shutdown.
>
0.5 s can still be an eternity (think: shell scripts, automated tests,
etc.) and that you ideally should use MHD_OPTION_NOTIFY_CONNECTION to
notify main() that you are "done". For example by doing a semaphore-down
operation/IPC write in main() and a semaphore-up()/IPC read in the
callback IF you are past quiesce and info tells you that you are the
last connection.
[Prev in Thread] | Current Thread | [Next in Thread] |