diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-07-20 10:36:26 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-07-20 10:36:26 +0000 |
commit | a559950eb866af16cffb6cfa9ac7d2fa12274f73 (patch) | |
tree | 619454928f0bd787d8323cd1f12e1da086e50c7f | |
parent | edb0845e3542c9b606e45a4606b6bff57e1f98aa (diff) | |
download | libmicrohttpd-a559950eb866af16cffb6cfa9ac7d2fa12274f73.tar.gz libmicrohttpd-a559950eb866af16cffb6cfa9ac7d2fa12274f73.zip |
-fix combining HTTPS and EPOLL
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/examples/benchmark_https.c | 2 | ||||
-rw-r--r-- | src/microhttpd/connection.c | 97 | ||||
-rw-r--r-- | src/microhttpd/connection.h | 14 | ||||
-rw-r--r-- | src/microhttpd/connection_https.c | 5 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 4 |
6 files changed, 90 insertions, 35 deletions
@@ -1,3 +1,6 @@ | |||
1 | Sat Jul 20 12:35:40 CEST 2013 | ||
2 | Fixing combination of MHD_USE_SSL and MHD_USE_EPOLL_LINUX_ONLY. -CG | ||
3 | |||
1 | Fri Jul 19 09:57:27 CEST 2013 | 4 | Fri 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 | */ | ||
2025 | static void | ||
2026 | cleanup_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 | */ | ||
2492 | int | ||
2493 | MHD_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 | */ | ||
105 | int | ||
106 | MHD_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) | |||
131 | static int | 131 | static int |
132 | MHD_tls_connection_handle_idle (struct MHD_Connection *connection) | 132 | MHD_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; |