Explorar o código

-fixes to MHD_suspend_connection

Christian Grothoff %!s(int64=12) %!d(string=hai) anos
pai
achega
74e0a68567
Modificáronse 6 ficheiros con 68 adicións e 46 borrados
  1. 1 0
      AUTHORS
  2. 5 0
      ChangeLog
  3. 1 1
      configure.ac
  4. 6 1
      src/microhttpd/connection.c
  5. 49 42
      src/microhttpd/daemon.c
  6. 6 2
      src/microhttpd/internal.h

+ 1 - 0
AUTHORS

@@ -44,6 +44,7 @@ Brecht Sanders <[email protected]>
 Jan Janak <[email protected]>
 Matthew Mundell <[email protected]>
 Scott Goldman <[email protected]>
+Jared Cantwell
 
 Documentation contributions also came from:
 Marco Maggi <[email protected]>

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+Sun Nov 24 13:41:15 CET 2013
+	Introduce state to mark connections in suspended state (with
+	epoll); add missing locking operations in MHD_suspend_connection.
+	Fix definition of MHD_TLS_CONNECTION_INIT.  -MH/JC
+
 Wed Oct 30 09:34:20 CET 2013
 	Fixing issue in PostProcessor when getting partial boundary
 	at the beginning, expanding test suite. -CG

+ 1 - 1
configure.ac

@@ -22,7 +22,7 @@
 #
 AC_PREREQ(2.57)
 AC_INIT([libmicrohttpd], [0.9.31],[[email protected]])
-AM_INIT_AUTOMAKE([silent-rules serial-tests])
+AM_INIT_AUTOMAKE([silent-rules])
 AC_CONFIG_HEADERS([MHD_config.h])
 AC_CONFIG_MACRO_DIR([m4])
 AH_TOP([#define _GNU_SOURCE  1])

+ 6 - 1
src/microhttpd/connection.c

@@ -2474,6 +2474,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
     {
     case MHD_EVENT_LOOP_INFO_READ:
       if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
+           (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
 	   (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
 	{
 	  EDLL_insert (daemon->eready_head,
@@ -2485,6 +2486,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
     case MHD_EVENT_LOOP_INFO_WRITE:
       if ( (connection->read_buffer_size > connection->read_buffer_offset) &&
 	   (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
+           (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
 	   (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
 	{
 	  EDLL_insert (daemon->eready_head,
@@ -2493,6 +2495,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
 	  connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
 	}
       if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
+           (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
 	   (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
 	{
 	  EDLL_insert (daemon->eready_head,
@@ -2504,7 +2507,8 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
     case MHD_EVENT_LOOP_INFO_BLOCK:
       /* we should look at this connection again in the next iteration
 	 of the event loop, as we're waiting on the application */
-      if (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+      if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) &&
+           (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) )
 	{
 	  EDLL_insert (daemon->eready_head,
 		       daemon->eready_tail,
@@ -2539,6 +2543,7 @@ MHD_connection_epoll_update_ (struct MHD_Connection *connection)
 
   if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
        (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) &&
+       (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
        ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ||
 	 ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
 	   ( (MHD_EVENT_LOOP_INFO_READ == connection->event_loop_info) ||

+ 49 - 42
src/microhttpd/daemon.c

@@ -1398,6 +1398,9 @@ MHD_suspend_connection (struct MHD_Connection *connection)
   daemon = connection->daemon;
   if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
     MHD_PANIC ("Cannot suspend connections in THREAD_PER_CONNECTION mode!\n");
+  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+       (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
+    MHD_PANIC ("Failed to acquire cleanup mutex\n");
   DLL_remove (daemon->connections_head,
               daemon->connections_tail,
               connection);
@@ -1410,22 +1413,29 @@ MHD_suspend_connection (struct MHD_Connection *connection)
                  daemon->manual_timeout_tail,
                  connection);
 #if EPOLL_SUPPORT
-  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
-    {
-      EDLL_remove (daemon->eready_head,
-                   daemon->eready_tail,
-                   connection);
-    }
-  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
-    {
-      if (0 != epoll_ctl (daemon->epoll_fd,
-                          EPOLL_CTL_DEL,
-                          connection->socket_fd,
-                          NULL))
-        MHD_PANIC ("Failed to remove FD from epoll set\n");
-      connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
-    }
+  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
+  {
+    if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+      {
+        EDLL_remove (daemon->eready_head,
+                     daemon->eready_tail,
+                     connection);
+      }
+    if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
+      {
+        if (0 != epoll_ctl (daemon->epoll_fd,
+                            EPOLL_CTL_DEL,
+                            connection->socket_fd,
+                            NULL))
+          MHD_PANIC ("Failed to remove FD from epoll set\n");
+        connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
+      }
+    connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
+  }
 #endif
+  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+       (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
+    MHD_PANIC ("Failed to release cleanup mutex\n");
 }
 
 
@@ -1460,33 +1470,30 @@ MHD_resume_connection (struct MHD_Connection *connection)
                  daemon->manual_timeout_tail,
                  connection);
 #if EPOLL_SUPPORT
-  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
-    {
-      EDLL_insert (daemon->eready_head,
-                   daemon->eready_tail,
-                   connection);
-    }
-  else
-    {
-      struct epoll_event event;
-
-      event.events = EPOLLIN | EPOLLOUT | EPOLLET;
-      event.data.ptr = connection;
-      if (0 != epoll_ctl (daemon->epoll_fd,
-                          EPOLL_CTL_ADD,
-                          connection->socket_fd,
-                          &event))
-        {
-#if HAVE_MESSAGES
-          MHD_DLOG (daemon,
-                    "Call to epoll_ctl failed: %s\n",
-                    STRERROR (errno));
-#endif
-          /* and now, good luck with this... */
-        }
-      else
-        connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
-    }
+  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
+  {
+    if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+      {
+        EDLL_insert (daemon->eready_head,
+                     daemon->eready_tail,
+                     connection);
+      }
+    else
+      {
+        struct epoll_event event;
+
+        event.events = EPOLLIN | EPOLLOUT | EPOLLET;
+        event.data.ptr = connection;
+        if (0 != epoll_ctl (daemon->epoll_fd,
+                            EPOLL_CTL_ADD,
+                            connection->socket_fd,
+                            &event))
+          MHD_PANIC ("Failed to add FD to epoll set\n");
+        else
+          connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
+    }
+    connection->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
+  }
 #endif
   if ( (-1 != daemon->wpipe[1]) &&
        (1 != WRITE (daemon->wpipe[1], "n", 1)) )

+ 6 - 2
src/microhttpd/internal.h

@@ -116,8 +116,12 @@ enum MHD_EpollState
     /**
      * Is this connection currently in the 'epoll' set?
      */
-    MHD_EPOLL_STATE_IN_EPOLL_SET = 8
+    MHD_EPOLL_STATE_IN_EPOLL_SET = 8,
 
+    /**
+     * Is this connection currently suspended?
+     */
+    MHD_EPOLL_STATE_SUSPENDED = 16
   };
 
 
@@ -452,7 +456,7 @@ enum MHD_CONNECTION_STATE
    * Handshake messages will be processed in this state & while
    * in the 'MHD_TLS_HELLO_REQUEST' state
    */
-  MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_CLOSED + 1
+  MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1
 
 };