I guess i found a problem with suspended connections. There is a
scenarion where one can resume a connection and then stop the daemon
without gives the daemon the oportunity to really resume the connection.
In this case, microhttpd will abort telling one that there is suspended
connection (because the connection is still in the daemon's suspended
list).
The following patch solves the problem (i've this problem using external
mainloop).
Regards,
Flavio Ceolin
Hey,
I'm debugging a problem with a crash in MHD_select_thread. We had
MHD_start_daemon_va fail while creating worker threads with the following
error: "file descriptor for worker control pipe exceeds maximum value". We
know what caused this error and are fixing it. But the problem was that a
MHD_select_thread worker thread was left running in the background after
MHD_start_daemon_va returned failure. I think the problem is from this
code in the thread_failed case in daemon.c:
/* Shutdown worker threads we've already created. Pretend
as though we had fully initialized our daemon, but
with a smaller number of threads than had been
requested. */
daemon->worker_pool_size = i - 1;
MHD_stop_daemon (daemon);
return NULL;
From the code, it looks like "i" is actually the number of threads that
were successfully created, so the "i - 1" in this code will leave an extra
thread hanging since MHD_stop_daemon will clean up one less thread than it
should. I'll probably try to work up a test to verify removing the "- 1"
is correct, but that could take me some time so I wanted to make sure I
wasn't missing something obvious before heading down that path.
~JareD
He is right, this patch fixes it.
The MHD goes in a busy loop when it is configured with MHD_USE_POLL_INTERNALLY and a connection times out.
When the connection times out, the connection is closed at connection.c:2646, which sets connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP.
When the loop info is set to MHD_EVENT_LOOP_INFO_CLEANUP, the main function of the thread loop, MHD_poll_all, never calls back the connection idle callback, which would have cleaned the connection and exit the loop.
I resolved the issue in my development code by adding pos->idle_handler (pos) at daemon.c:2477 in MHD_poll_all (SVN 35533).
The busy loop could be tested using a small enough connection timeout and netcat:
nc -v -w 100 <IP ADDRESS> <IP PORT>
CPU usage will reach 100% in one of the CPU and will remain at that level even when the netcat has closed its end of the connection.
Thanks,
Louis Benoit
Louis wrote:
There is a change of behavior between 0.9.37 and 0.9.38.
When a client adds a "Connection: close" header in 0.9.37, MHD adds a "Connection: close" header to its response and then
close the connection (as suggested in rfc2616, section 8.1.2.1).
The "Connection: close" header is not added in 0.9.38.
I looked into the 0.9.38 code and the code that prevents the inclusion of the "Connection: close" header is at line 773 of connection.c.
if ( ( (NULL != client_requested_close) ||
(MHD_YES == connection->read_closed) ) &&
(NULL == response_has_close) &&
(0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
must_add_close = MHD_YES;
Shouldn't it read
if ( ( (NULL != client_requested_close) ||
(MHD_YES == connection->read_closed) ||
(0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) ) &&
(NULL == response_has_close) )
must_add_close = MHD_YES;
Thanks,
Louis Benoit