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. >
And while Evgeny is 100% correct, let me point out the opposite concern: 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.
signature.asc
Description: OpenPGP digital signature