gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [libmicrohttpd] branch master updated: Reworked handling "a


From: gnunet
Subject: [GNUnet-SVN] [libmicrohttpd] branch master updated: Reworked handling "already ready" situations: * busy-waiting for write if TLS connection is in MHD_EVENT_LOOP_INFO_WRITE mode and data is pending in TLS buffers * removed calculation of number of TLS read-ready connections * simplified and unified processing if any connection is in MHD_EVENT_LOOP_INFO_BLOCK mode
Date: Sun, 26 Feb 2017 21:47:45 +0100

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

The following commit(s) were added to refs/heads/master by this push:
     new dd2d724c Reworked handling "already ready" situations: * busy-waiting 
for write if TLS connection is in MHD_EVENT_LOOP_INFO_WRITE mode and data is 
pending in TLS buffers * removed calculation of number of TLS read-ready 
connections * simplified and unified processing if any connection is in 
MHD_EVENT_LOOP_INFO_BLOCK mode
dd2d724c is described below

commit dd2d724c197d6fb5c3d676ae786763190ef278c5
Author: Evgeny Grin (Karlson2k) <address@hidden>
AuthorDate: Sun Feb 26 23:34:20 2017 +0300

    Reworked handling "already ready" situations:
    * busy-waiting for write if TLS connection is in MHD_EVENT_LOOP_INFO_WRITE 
mode and data is pending in TLS buffers
    * removed calculation of number of TLS read-ready connections
    * simplified and unified processing if any connection is in 
MHD_EVENT_LOOP_INFO_BLOCK mode
---
 src/microhttpd/daemon.c   | 106 ++++++++++++++++++++++++----------------------
 src/microhttpd/internal.h |  25 +++++------
 2 files changed, 67 insertions(+), 64 deletions(-)

diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index b52f05e7..b93367b8 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -428,11 +428,6 @@ recv_tls_adapter (struct MHD_Connection *connection,
 {
   ssize_t res;
 
-  if (connection->tls_read_ready)
-    {
-      connection->daemon->num_tls_read_ready--;
-      connection->tls_read_ready = false;
-    }
   res = gnutls_record_recv (connection->tls_session,
                             other,
                             (i > SSIZE_MAX) ? SSIZE_MAX : i);
@@ -451,13 +446,13 @@ recv_tls_adapter (struct MHD_Connection *connection,
         disrupted); set errno to something caller will interpret
         correctly as a hard error */
       MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_);
+      connection->tls_read_ready = false;
       return res;
     }
-  if ((size_t)res == i)
-    {
-      connection->tls_read_ready = true;
-      connection->daemon->num_tls_read_ready++;
-    }
+
+  /* Check whether TLS buffers still have some unread data. */
+  connection->tls_read_ready = ( ((size_t)res == i) &&
+                                 (0 != gnutls_record_check_pending 
(connection->tls_session)) );
   return res;
 }
 
@@ -951,6 +946,23 @@ call_handlers (struct MHD_Connection *con,
           ret = con->idle_handler (con);
         }
     }
+
+  /* All connection's data and states are processed for this turn.
+   * If connection already has more data to be processed - use
+   * zero timeout for next select()/poll(). */
+  /* Thread-per-connection do not need global zero timeout as
+   * connections are processed individually. */
+  if ( (!con->daemon->data_already_pending) &&
+       (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
+    {
+      if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
+        con->daemon->data_already_pending = true;
+#ifdef HTTPS_SUPPORT
+      else if ( (con->tls_read_ready) &&
+                (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) )
+        con->daemon->data_already_pending = true;
+#endif /* HTTPS_SUPPORT */
+    }
   return ret;
 }
 
@@ -1061,7 +1073,6 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
           if (0 < gnutls_record_check_pending (urh->connection->tls_session))
             {
               urh->connection->tls_read_ready = true;
-              urh->connection->daemon->has_tls_recv_ready = true;
             }
         }
       else if (0 >= res)
@@ -1238,6 +1249,13 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
         }
     }
 
+  /* Check whether data is present in TLS buffers
+   * and incoming forward buffer have some space. */
+  if ( (urh->connection->tls_read_ready) &&
+       (urh->in_buffer_used < urh->in_buffer_size) &&
+       (0 == (urh->connection->daemon->options & 
MHD_USE_THREAD_PER_CONNECTION)) )
+    urh->connection->daemon->data_already_pending = true;
+
   if ( (urh->connection->daemon->shutdown) &&
        ( (0 != urh->out_buffer_size) ||
          (0 != urh->out_buffer_used) ) )
@@ -1312,7 +1330,8 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
             {
               struct timeval* tvp;
               struct timeval tv;
-              if (con->tls_read_ready)
+              if ( (con->tls_read_ready) &&
+                   (urh->in_buffer_used < urh->in_buffer_size))
                 { /* No need to wait if incoming data is already pending in 
TLS buffers. */
                   tv.tv_sec = 0;
                   tv.tv_usec = 0;
@@ -1378,7 +1397,8 @@ thread_main_connection_upgrade (struct MHD_Connection 
*con)
           if (0 != urh->in_buffer_used)
             p[1].events |= POLLOUT;
 
-          if (con->tls_read_ready)
+          if ( (con->tls_read_ready) &&
+               (urh->in_buffer_used < urh->in_buffer_size))
             timeout = 0; /* No need to wait if incoming data is already 
pending in TLS buffers. */
           else
             timeout = UINT_MAX;
@@ -1548,15 +1568,20 @@ thread_main_handle_connection (void *data)
         }
 
       tvp = NULL;
+
+      if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
 #ifdef HTTPS_SUPPORT
-      if (con->tls_read_ready)
+           || ( (con->tls_read_ready) &&
+                (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) )
+#endif /* HTTPS_SUPPORT */
+         )
        {
-         /* do not block (more data may be inside of TLS buffers waiting for 
us) */
+         /* do not block: more data may be inside of TLS buffers waiting or
+          * application must provide response data */
          tv.tv_sec = 0;
          tv.tv_usec = 0;
          tvp = &tv;
        }
-#endif /* HTTPS_SUPPORT */
       if ( (NULL == tvp) &&
            (timeout > 0) )
        {
@@ -1609,9 +1634,6 @@ thread_main_handle_connection (void *data)
                                         &maxsock,
                                         FD_SETSIZE))
                err_state = true;
-             tv.tv_sec = 0;
-             tv.tv_usec = 0;
-             tvp = &tv;
              break;
            case MHD_EVENT_LOOP_INFO_CLEANUP:
              /* how did we get here!? */
@@ -1691,9 +1713,6 @@ thread_main_handle_connection (void *data)
              break;
            case MHD_EVENT_LOOP_INFO_BLOCK:
              p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
-             tv.tv_sec = 0;
-             tv.tv_usec = 0;
-             tvp = &tv;
              break;
            case MHD_EVENT_LOOP_INFO_CLEANUP:
              /* how did we get here!? */
@@ -2905,15 +2924,13 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
       return MHD_NO;
     }
 
-#ifdef HTTPS_SUPPORT
-  if (0 != daemon->num_tls_read_ready || daemon->has_tls_recv_ready)
+  if (daemon->data_already_pending)
     {
-      /* if there is any TLS connection with data ready for
-        reading, we must not block in the event loop */
+      /* Some data already waiting to be processed. */
       *timeout = 0;
       return MHD_YES;
     }
-#endif /* HTTPS_SUPPORT */
+
 #ifdef EPOLL_SUPPORT
   if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
        (NULL != daemon->eready_head) )
@@ -3009,6 +3026,10 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
   unsigned int mask = MHD_ALLOW_SUSPEND_RESUME | MHD_USE_EPOLL_INTERNAL_THREAD 
|
     MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_POLL_INTERNAL_THREAD;
 
+  /* Reset. New value will be set when connections are processed. */
+  /* Note: no-op for thread-per-connection as it is always false in that mode. 
*/
+  daemon->data_already_pending = false;
+
   /* Clear ITC to avoid spinning select */
   /* Do it before any other processing so new signals
      will trigger select again and will be processed */
@@ -3017,14 +3038,6 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
                   read_fd_set)) )
     MHD_itc_clear_ (daemon->itc);
 
-#ifdef HTTPS_SUPPORT
-    /* Reset TLS read-ready.
-     * New value will be set by read handlers. */
-    if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
-         (0 != (daemon->options & MHD_USE_TLS)) )
-      daemon->has_tls_recv_ready = 0;
-#endif /* HTTPS_SUPPORT */
-
   /* Resuming external connections when using an extern mainloop  */
   if (MHD_ALLOW_SUSPEND_RESUME == (daemon->options & mask))
     resume_suspended_connections (daemon);
@@ -3364,7 +3377,6 @@ MHD_poll_all (struct MHD_Daemon *daemon,
            break;
          case MHD_EVENT_LOOP_INFO_BLOCK:
            p[poll_server+i].events |=  MHD_POLL_EVENTS_ERR_DISC;
-           timeout = 0;
            break;
          case MHD_EVENT_LOOP_INFO_CLEANUP:
            timeout = 0; /* clean up "pos" immediately */
@@ -3412,6 +3424,10 @@ MHD_poll_all (struct MHD_Daemon *daemon,
         free(p);
        return MHD_NO;
       }
+
+    /* Reset. New value will be set when connections are processed. */
+    daemon->data_already_pending = false;
+
     /* handle ITC FD */
     /* do it before any other processing so
        new signals will be processed in next loop */
@@ -3419,14 +3435,6 @@ MHD_poll_all (struct MHD_Daemon *daemon,
          (0 != (p[poll_itc_idx].revents & POLLIN)) )
       MHD_itc_clear_ (daemon->itc);
 
-#ifdef HTTPS_SUPPORT
-    /* Reset TLS read-ready.
-     * New value will be set by read handlers. */
-    if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
-         (0 != (daemon->options & MHD_USE_TLS)) )
-      daemon->has_tls_recv_ready = 0;
-#endif /* HTTPS_SUPPORT */
-
     /* handle shutdown */
     if (daemon->shutdown)
       {
@@ -3816,12 +3824,10 @@ MHD_epoll (struct MHD_Daemon *daemon,
   else
     timeout_ms = 0;
 
-#ifdef HTTPS_SUPPORT
-  /* Reset TLS read-ready.
-   * New value will be set by read handlers. */
-  if ( 0 != (daemon->options & MHD_USE_TLS) )
-    daemon->has_tls_recv_ready = false;
-#endif /* HTTPS_SUPPORT */
+  /* Reset. New value will be set when connections are processed. */
+  /* Note: Used mostly for uniformity here as same situation is
+   * signaled in epoll mode by non-empty eready DLL. */
+  daemon->data_already_pending = false;
 
   /* drain 'epoll' event queue; need to iterate as we get at most
      MAX_EVENTS in one system call here; in practice this should
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 4f2eac38..4979474b 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -1452,6 +1452,17 @@ struct MHD_Daemon
   bool resuming;
 
   /**
+   * 'True' if some data is already waiting to be processed.
+   * If set to 'true' - zero timeout for select()/poll*()
+   * is used.
+   * Should be reset each time before processing connections
+   * and raised by any connection which require additional
+   * immediately processing (application does not provide
+   * data for response, data waiting in TLS buffers etc.)
+   */
+  bool data_already_pending;
+
+  /**
    * Number of active parallel connections.
    */
   unsigned int connections;
@@ -1559,20 +1570,6 @@ struct MHD_Daemon
    */
   bool have_dhparams;
 
-  /**
-   * For how many connections do we have 'tls_read_ready' set to MHD_YES?
-   * Used to avoid O(n) traversal over all connections when determining
-   * event-loop timeout (as it needs to be zero if there is any connection
-   * which might have ready data within TLS).
-   */
-  unsigned int num_tls_read_ready;
-
-  /**
-   * Indicate that some TLS connection(s) have received data pending in
-   * TLS buffers.
-   */
-  bool has_tls_recv_ready;
-
 #endif /* HTTPS_SUPPORT */
 
 #ifdef DAUTH_SUPPORT

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]