From 086ba366b757984dc68577aaa6dac7b2d5a7c2ac Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 9 Apr 2015 07:03:26 +0000 Subject: [PATCH] Hi all, 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 --- AUTHORS | 1 + ChangeLog | 5 +++++ src/microhttpd/daemon.c | 9 +++++++++ 3 files changed, 15 insertions(+) diff --git a/AUTHORS b/AUTHORS index cc11a96f..a441dfa8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -52,6 +52,7 @@ Sree Harsha Totakura Hani Benhabiles Guy Martin Robert Groenenberg +Denis Dowling Documentation contributions also came from: diff --git a/ChangeLog b/ChangeLog index cb9f7842..102b92cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index bd952ce3..24310d22 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c @@ -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; }