I was trying to use MHD_suspend_connection() and MHD_resume_connection() to implement long polling on a request. I am using options MHD_USE_SELECT_INTERNALLY and MHD_USE_POLL options. I noticed the server thread went to 100% CPU after the first MHD_resume_connection() call. Looking at the code in MHD_poll_all() I can see that the file descriptor from daemon->wpipe[0] gets inserted into the list of file descriptors to poll but this file descriptor is never read so every time this function is called it returns immediately. The code works fine if I drop to using just MHD_USE_SELECT_INTERNALLY.

The patch below fixes the problem.

Regards,
Denis
This commit is contained in:
Christian Grothoff
2015-04-09 07:03:26 +00:00
parent 741ca49079
commit 086ba366b7
3 changed files with 15 additions and 0 deletions
+1
View File
@@ -52,6 +52,7 @@ Sree Harsha Totakura <sreeharsha@totakura.in>
Hani Benhabiles <kroosec@gmail.com>
Guy Martin <gmsoft@tuxicoman.be>
Robert Groenenberg <robert.groenenberg@broadforward.com>
Denis Dowling <denis.dowling@hsd.com.au>
Documentation contributions also came from:
+5
View File
@@ -1,3 +1,8 @@
Thu Apr 9 09:01:15 CEST 2015
Fixing issue with undrained signal pipe when using
MHD_USE_SELECT_INTERNALLY and MHD_USE_POLL in combination
with MHD_resume_connection(), causing 100% CPU usage. -DD
Tue Apr 7 00:12:36 CEST 2015
Releasing libmicrohttpd 0.9.40. -CG
+9
View File
@@ -2317,6 +2317,8 @@ MHD_poll_all (struct MHD_Daemon *daemon,
int timeout;
unsigned int poll_server;
int poll_listen;
int poll_pipe;
char tmp;
memset (p, 0, sizeof (p));
poll_server = 0;
@@ -2331,11 +2333,13 @@ MHD_poll_all (struct MHD_Daemon *daemon,
poll_listen = (int) poll_server;
poll_server++;
}
poll_pipe = -1;
if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
{
p[poll_server].fd = daemon->wpipe[0];
p[poll_server].events = POLLIN;
p[poll_server].revents = 0;
poll_pipe = (int) poll_server;
poll_server++;
}
if (may_block == MHD_NO)
@@ -2433,6 +2437,11 @@ MHD_poll_all (struct MHD_Daemon *daemon,
if ( (-1 != poll_listen) &&
(0 != (p[poll_listen].revents & POLLIN)) )
(void) MHD_accept_connection (daemon);
/* handle pipe FD */
if ( (-1 != poll_pipe) &&
(0 != (p[poll_pipe].revents & POLLIN)) )
(void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
}
return MHD_YES;
}