[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [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,
gnunet <=