aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-07-20 10:36:26 +0000
committerChristian Grothoff <christian@grothoff.org>2013-07-20 10:36:26 +0000
commita559950eb866af16cffb6cfa9ac7d2fa12274f73 (patch)
tree619454928f0bd787d8323cd1f12e1da086e50c7f
parentedb0845e3542c9b606e45a4606b6bff57e1f98aa (diff)
downloadlibmicrohttpd-a559950eb866af16cffb6cfa9ac7d2fa12274f73.tar.gz
libmicrohttpd-a559950eb866af16cffb6cfa9ac7d2fa12274f73.zip
-fix combining HTTPS and EPOLL
-rw-r--r--ChangeLog3
-rw-r--r--src/examples/benchmark_https.c2
-rw-r--r--src/microhttpd/connection.c97
-rw-r--r--src/microhttpd/connection.h14
-rw-r--r--src/microhttpd/connection_https.c5
-rw-r--r--src/microhttpd/daemon.c4
6 files changed, 90 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 58b754f0..7aedb0a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
1Sat Jul 20 12:35:40 CEST 2013
2 Fixing combination of MHD_USE_SSL and MHD_USE_EPOLL_LINUX_ONLY. -CG
3
1Fri Jul 19 09:57:27 CEST 2013 4Fri Jul 19 09:57:27 CEST 2013
2 Fix issue where connections were not cleaned up when 5 Fix issue where connections were not cleaned up when
3 'MHD_run_from_select' was used. Adding experimental 6 'MHD_run_from_select' was used. Adding experimental
diff --git a/src/examples/benchmark_https.c b/src/examples/benchmark_https.c
index 3e79fe6f..e2b55af4 100644
--- a/src/examples/benchmark_https.c
+++ b/src/examples/benchmark_https.c
@@ -178,7 +178,7 @@ main (int argc, char *const *argv)
178 "close"); 178 "close");
179 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_SUPPRESS_DATE_NO_CLOCK | MHD_USE_SSL 179 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_SUPPRESS_DATE_NO_CLOCK | MHD_USE_SSL
180#if EPOLL_SUPPORT 180#if EPOLL_SUPPORT
181 | MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_TURBO 181 | MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_TURBO
182#endif 182#endif
183 , 183 ,
184 atoi (argv[1]), 184 atoi (argv[1]),
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index de67f800..984c9247 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2017,6 +2017,46 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2017 2017
2018 2018
2019/** 2019/**
2020 * Clean up the state of the given connection and move it into the
2021 * clean up queue for final disposal.
2022 *
2023 * @param connection handle for the connection to clean up
2024 */
2025static void
2026cleanup_connection (struct MHD_Connection *connection)
2027{
2028 struct MHD_Daemon *daemon = connection->daemon;
2029
2030 if (NULL != connection->response)
2031 {
2032 MHD_destroy_response (connection->response);
2033 connection->response = NULL;
2034 }
2035 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2036 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
2037 MHD_PANIC ("Failed to acquire cleanup mutex\n");
2038 if (connection->connection_timeout == daemon->connection_timeout)
2039 XDLL_remove (daemon->normal_timeout_head,
2040 daemon->normal_timeout_tail,
2041 connection);
2042 else
2043 XDLL_remove (daemon->manual_timeout_head,
2044 daemon->manual_timeout_tail,
2045 connection);
2046 DLL_remove (daemon->connections_head,
2047 daemon->connections_tail,
2048 connection);
2049 DLL_insert (daemon->cleanup_head,
2050 daemon->cleanup_tail,
2051 connection);
2052 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2053 (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) )
2054 MHD_PANIC ("Failed to release cleanup mutex\n");
2055 connection->in_idle = MHD_NO;
2056}
2057
2058
2059/**
2020 * This function was created to handle per-connection processing that 2060 * This function was created to handle per-connection processing that
2021 * has to happen even if the socket cannot be read or written to. 2061 * has to happen even if the socket cannot be read or written to.
2022 * 2062 *
@@ -2378,7 +2418,8 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2378 } 2418 }
2379 continue; 2419 continue;
2380 case MHD_CONNECTION_CLOSED: 2420 case MHD_CONNECTION_CLOSED:
2381 goto cleanup_connection; 2421 cleanup_connection (connection);
2422 return MHD_NO;
2382 default: 2423 default:
2383 EXTRA_CHECK (0); 2424 EXTRA_CHECK (0);
2384 break; 2425 break;
@@ -2431,8 +2472,28 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2431 /* This connection is finished, nothing left to do */ 2472 /* This connection is finished, nothing left to do */
2432 break; 2473 break;
2433 } 2474 }
2475#if EPOLL_SUPPORT
2476 return MHD_connection_epoll_update_ (connection);
2477#else
2478 return MHD_YES;
2479#endif
2480}
2481
2434 2482
2435#if EPOLL_SUPPORT 2483#if EPOLL_SUPPORT
2484/**
2485 * Perform epoll processing, possibly moving the connection back into
2486 * the epoll set if needed.
2487 *
2488 * @param connection connection to process
2489 * @return MHD_YES if we should continue to process the
2490 * connection (not dead yet), MHD_NO if it died
2491 */
2492int
2493MHD_connection_epoll_update_ (struct MHD_Connection *connection)
2494{
2495 struct MHD_Daemon *daemon = connection->daemon;
2496
2436 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && 2497 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2437 (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) && 2498 (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) &&
2438 ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) || 2499 ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ||
@@ -2457,43 +2518,15 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
2457 STRERROR (errno)); 2518 STRERROR (errno));
2458#endif 2519#endif
2459 connection->state = MHD_CONNECTION_CLOSED; 2520 connection->state = MHD_CONNECTION_CLOSED;
2460 goto cleanup_connection; 2521 cleanup_connection (connection);
2522 return MHD_NO;
2461 } 2523 }
2462 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; 2524 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2463 } 2525 }
2464#endif
2465 connection->in_idle = MHD_NO; 2526 connection->in_idle = MHD_NO;
2466 return MHD_YES; 2527 return MHD_YES;
2467
2468 cleanup_connection:
2469 if (NULL != connection->response)
2470 {
2471 MHD_destroy_response (connection->response);
2472 connection->response = NULL;
2473 }
2474 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2475 (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
2476 MHD_PANIC ("Failed to acquire cleanup mutex\n");
2477 if (connection->connection_timeout == daemon->connection_timeout)
2478 XDLL_remove (daemon->normal_timeout_head,
2479 daemon->normal_timeout_tail,
2480 connection);
2481 else
2482 XDLL_remove (daemon->manual_timeout_head,
2483 daemon->manual_timeout_tail,
2484 connection);
2485 DLL_remove (daemon->connections_head,
2486 daemon->connections_tail,
2487 connection);
2488 DLL_insert (daemon->cleanup_head,
2489 daemon->cleanup_tail,
2490 connection);
2491 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2492 (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) )
2493 MHD_PANIC ("Failed to release cleanup mutex\n");
2494 connection->in_idle = MHD_NO;
2495 return MHD_NO;
2496} 2528}
2529#endif
2497 2530
2498 2531
2499/** 2532/**
diff --git a/src/microhttpd/connection.h b/src/microhttpd/connection.h
index 985f29ed..365e39b4 100644
--- a/src/microhttpd/connection.h
+++ b/src/microhttpd/connection.h
@@ -93,4 +93,18 @@ MHD_connection_close (struct MHD_Connection *connection,
93 enum MHD_RequestTerminationCode termination_code); 93 enum MHD_RequestTerminationCode termination_code);
94 94
95 95
96#if EPOLL_SUPPORT
97/**
98 * Perform epoll processing, possibly moving the connection back into
99 * the epoll set if needed.
100 *
101 * @param connection connection to process
102 * @return MHD_YES if we should continue to process the
103 * connection (not dead yet), MHD_NO if it died
104 */
105int
106MHD_connection_epoll_update_ (struct MHD_Connection *connection);
107#endif
108
109
96#endif 110#endif
diff --git a/src/microhttpd/connection_https.c b/src/microhttpd/connection_https.c
index b0be3ced..0b764eb7 100644
--- a/src/microhttpd/connection_https.c
+++ b/src/microhttpd/connection_https.c
@@ -131,6 +131,7 @@ MHD_tls_connection_handle_write (struct MHD_Connection *connection)
131static int 131static int
132MHD_tls_connection_handle_idle (struct MHD_Connection *connection) 132MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
133{ 133{
134 struct MHD_Daemon *daemon = connection->daemon;
134 unsigned int timeout; 135 unsigned int timeout;
135 136
136#if DEBUG_STATES 137#if DEBUG_STATES
@@ -145,7 +146,7 @@ MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
145 { 146 {
146 /* on newly created connections we might reach here before any reply has been received */ 147 /* on newly created connections we might reach here before any reply has been received */
147 case MHD_TLS_CONNECTION_INIT: 148 case MHD_TLS_CONNECTION_INIT:
148 return MHD_YES; 149 break;
149 /* close connection if necessary */ 150 /* close connection if necessary */
150 case MHD_CONNECTION_CLOSED: 151 case MHD_CONNECTION_CLOSED:
151 gnutls_bye (connection->tls_session, GNUTLS_SHUT_RDWR); 152 gnutls_bye (connection->tls_session, GNUTLS_SHUT_RDWR);
@@ -156,7 +157,7 @@ MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
156 return MHD_YES; 157 return MHD_YES;
157 return MHD_connection_handle_idle (connection); 158 return MHD_connection_handle_idle (connection);
158 } 159 }
159 return MHD_YES; 160 return MHD_connection_epoll_update_ (connection);
160} 161}
161 162
162 163
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index d111d9cd..f92c1f29 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -400,7 +400,9 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
400 if ( (GNUTLS_E_AGAIN == res) || 400 if ( (GNUTLS_E_AGAIN == res) ||
401 (GNUTLS_E_INTERRUPTED == res) ) 401 (GNUTLS_E_INTERRUPTED == res) )
402 { 402 {
403 fprintf (stderr, "RAGAIN!\n");
403 errno = EINTR; 404 errno = EINTR;
405 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
404 return -1; 406 return -1;
405 } 407 }
406 if (res < 0) 408 if (res < 0)
@@ -438,7 +440,9 @@ send_tls_adapter (struct MHD_Connection *connection,
438 if ( (GNUTLS_E_AGAIN == res) || 440 if ( (GNUTLS_E_AGAIN == res) ||
439 (GNUTLS_E_INTERRUPTED == res) ) 441 (GNUTLS_E_INTERRUPTED == res) )
440 { 442 {
443 fprintf (stderr, "WAGAIN!\n");
441 errno = EINTR; 444 errno = EINTR;
445 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
442 return -1; 446 return -1;
443 } 447 }
444 return res; 448 return res;