ソースを参照

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
Christian Grothoff 11 年 前
コミット
086ba366b7
3 ファイル変更15 行追加0 行削除
  1. 1 0
      AUTHORS
  2. 5 0
      ChangeLog
  3. 9 0
      src/microhttpd/daemon.c

+ 1 - 0
AUTHORS

@@ -52,6 +52,7 @@ Sree Harsha Totakura <[email protected]>
 Hani Benhabiles <[email protected]>
 Guy Martin <[email protected]>
 Robert Groenenberg <[email protected]>
+Denis Dowling <[email protected]>
 
 
 Documentation contributions also came from:

+ 5 - 0
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
 

+ 9 - 0
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;
 }