diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-03-15 19:31:42 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-03-15 19:31:42 +0000 |
commit | c932ba77fde49a5c22374de96b8e56b17e746462 (patch) | |
tree | f6b0b5ad646b9089d3b7e8a95957e01cd14a0620 | |
parent | d3b17d3b19ad509e6e355677cc7fea73eb15c1b9 (diff) | |
download | libmicrohttpd-c932ba77fde49a5c22374de96b8e56b17e746462.tar.gz libmicrohttpd-c932ba77fde49a5c22374de96b8e56b17e746462.zip |
fix unnecessary and potentially problematic use of eready DLL in thread-per-connection mode
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/include/microhttpd.h | 2 | ||||
-rw-r--r-- | src/microhttpd/connection.c | 83 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 54 |
4 files changed, 76 insertions, 67 deletions
@@ -1,3 +1,7 @@ | |||
1 | Tue Mar 15 20:29:34 CET 2016 | ||
2 | Do not use eready DLL data structure unless | ||
3 | we are actually using epoll(). -DD/CG | ||
4 | |||
1 | Fri Feb 5 20:43:11 CET 2016 | 5 | Fri Feb 5 20:43:11 CET 2016 |
2 | Fixed testsuite compile warning on W32. | 6 | Fixed testsuite compile warning on W32. |
3 | Added check test for triggering poll() on | 7 | Added check test for triggering poll() on |
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index c7f23c15..61eebb80 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h | |||
@@ -130,7 +130,7 @@ typedef intptr_t ssize_t; | |||
130 | * Current version of the library. | 130 | * Current version of the library. |
131 | * 0x01093001 = 1.9.30-1. | 131 | * 0x01093001 = 1.9.30-1. |
132 | */ | 132 | */ |
133 | #define MHD_VERSION 0x00094802 | 133 | #define MHD_VERSION 0x00094803 |
134 | 134 | ||
135 | /** | 135 | /** |
136 | * MHD-internal return code for "YES". | 136 | * MHD-internal return code for "YES". |
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index 0a9f9885..dc224588 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -2709,7 +2709,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
2709 | connection->state = MHD_CONNECTION_NORMAL_BODY_READY; | 2709 | connection->state = MHD_CONNECTION_NORMAL_BODY_READY; |
2710 | /* Buffering for flushable socket was already enabled*/ | 2710 | /* Buffering for flushable socket was already enabled*/ |
2711 | if (MHD_NO == socket_flush_possible (connection)) | 2711 | if (MHD_NO == socket_flush_possible (connection)) |
2712 | socket_start_no_buffering (connection); | 2712 | socket_start_no_buffering (connection); |
2713 | 2713 | ||
2714 | break; | 2714 | break; |
2715 | } | 2715 | } |
@@ -2737,7 +2737,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
2737 | connection->state = MHD_CONNECTION_CHUNKED_BODY_READY; | 2737 | connection->state = MHD_CONNECTION_CHUNKED_BODY_READY; |
2738 | /* Buffering for flushable socket was already enabled */ | 2738 | /* Buffering for flushable socket was already enabled */ |
2739 | if (MHD_NO == socket_flush_possible (connection)) | 2739 | if (MHD_NO == socket_flush_possible (connection)) |
2740 | socket_start_no_buffering (connection); | 2740 | socket_start_no_buffering (connection); |
2741 | 2741 | ||
2742 | continue; | 2742 | continue; |
2743 | } | 2743 | } |
@@ -2860,45 +2860,48 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
2860 | } | 2860 | } |
2861 | MHD_connection_update_event_loop_info (connection); | 2861 | MHD_connection_update_event_loop_info (connection); |
2862 | #if EPOLL_SUPPORT | 2862 | #if EPOLL_SUPPORT |
2863 | switch (connection->event_loop_info) | 2863 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
2864 | { | 2864 | { |
2865 | case MHD_EVENT_LOOP_INFO_READ: | 2865 | switch (connection->event_loop_info) |
2866 | if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) && | 2866 | { |
2867 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && | 2867 | case MHD_EVENT_LOOP_INFO_READ: |
2868 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) ) | 2868 | if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) && |
2869 | { | 2869 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && |
2870 | EDLL_insert (daemon->eready_head, | 2870 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) ) |
2871 | daemon->eready_tail, | 2871 | { |
2872 | connection); | 2872 | EDLL_insert (daemon->eready_head, |
2873 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 2873 | daemon->eready_tail, |
2874 | } | 2874 | connection); |
2875 | break; | 2875 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
2876 | case MHD_EVENT_LOOP_INFO_WRITE: | 2876 | } |
2877 | if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) && | 2877 | break; |
2878 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && | 2878 | case MHD_EVENT_LOOP_INFO_WRITE: |
2879 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) ) | 2879 | if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) && |
2880 | { | 2880 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && |
2881 | EDLL_insert (daemon->eready_head, | 2881 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) ) |
2882 | daemon->eready_tail, | 2882 | { |
2883 | connection); | 2883 | EDLL_insert (daemon->eready_head, |
2884 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 2884 | daemon->eready_tail, |
2885 | } | 2885 | connection); |
2886 | break; | 2886 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
2887 | case MHD_EVENT_LOOP_INFO_BLOCK: | 2887 | } |
2888 | /* we should look at this connection again in the next iteration | 2888 | break; |
2889 | of the event loop, as we're waiting on the application */ | 2889 | case MHD_EVENT_LOOP_INFO_BLOCK: |
2890 | if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) && | 2890 | /* we should look at this connection again in the next iteration |
2891 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) ) | 2891 | of the event loop, as we're waiting on the application */ |
2892 | { | 2892 | if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) && |
2893 | EDLL_insert (daemon->eready_head, | 2893 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) ) |
2894 | daemon->eready_tail, | 2894 | { |
2895 | connection); | 2895 | EDLL_insert (daemon->eready_head, |
2896 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 2896 | daemon->eready_tail, |
2897 | } | 2897 | connection); |
2898 | break; | 2898 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
2899 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 2899 | } |
2900 | /* This connection is finished, nothing left to do */ | 2900 | break; |
2901 | break; | 2901 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
2902 | /* This connection is finished, nothing left to do */ | ||
2903 | break; | ||
2904 | } | ||
2902 | } | 2905 | } |
2903 | return MHD_connection_epoll_update_ (connection); | 2906 | return MHD_connection_epoll_update_ (connection); |
2904 | #else | 2907 | #else |
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index bbd7b42d..14786042 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of libmicrohttpd | 2 | This file is part of libmicrohttpd |
3 | Copyright (C) 2007-2014 Daniel Pittman and Christian Grothoff | 3 | Copyright (C) 2007-2016 Daniel Pittman and Christian Grothoff |
4 | 4 | ||
5 | This library is free software; you can redistribute it and/or | 5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public | 6 | modify it under the terms of the GNU Lesser General Public |
@@ -2081,30 +2081,32 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
2081 | MHD_CONNECTION_NOTIFY_CLOSED); | 2081 | MHD_CONNECTION_NOTIFY_CLOSED); |
2082 | MHD_ip_limit_del (daemon, pos->addr, pos->addr_len); | 2082 | MHD_ip_limit_del (daemon, pos->addr, pos->addr_len); |
2083 | #if EPOLL_SUPPORT | 2083 | #if EPOLL_SUPPORT |
2084 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 2084 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
2085 | { | 2085 | { |
2086 | EDLL_remove (daemon->eready_head, | 2086 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
2087 | daemon->eready_tail, | 2087 | { |
2088 | pos); | 2088 | EDLL_remove (daemon->eready_head, |
2089 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | 2089 | daemon->eready_tail, |
2090 | } | 2090 | pos); |
2091 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && | 2091 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
2092 | (MHD_INVALID_SOCKET != daemon->epoll_fd) && | 2092 | } |
2093 | (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) | 2093 | if ( (MHD_INVALID_SOCKET != daemon->epoll_fd) && |
2094 | { | 2094 | (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) |
2095 | /* epoll documentation suggests that closing a FD | 2095 | { |
2096 | automatically removes it from the epoll set; however, | 2096 | /* epoll documentation suggests that closing a FD |
2097 | this is not true as if we fail to do manually remove it, | 2097 | automatically removes it from the epoll set; however, |
2098 | we are still seeing an event for this fd in epoll, | 2098 | this is not true as if we fail to do manually remove it, |
2099 | causing grief (use-after-free...) --- at least on my | 2099 | we are still seeing an event for this fd in epoll, |
2100 | system. */ | 2100 | causing grief (use-after-free...) --- at least on my |
2101 | if (0 != epoll_ctl (daemon->epoll_fd, | 2101 | system. */ |
2102 | EPOLL_CTL_DEL, | 2102 | if (0 != epoll_ctl (daemon->epoll_fd, |
2103 | pos->socket_fd, | 2103 | EPOLL_CTL_DEL, |
2104 | NULL)) | 2104 | pos->socket_fd, |
2105 | MHD_PANIC ("Failed to remove FD from epoll set\n"); | 2105 | NULL)) |
2106 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; | 2106 | MHD_PANIC ("Failed to remove FD from epoll set\n"); |
2107 | } | 2107 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; |
2108 | } | ||
2109 | } | ||
2108 | #endif | 2110 | #endif |
2109 | if (NULL != pos->response) | 2111 | if (NULL != pos->response) |
2110 | { | 2112 | { |
@@ -3766,7 +3768,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
3766 | if (0 == (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION))) | 3768 | if (0 == (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION))) |
3767 | use_pipe = 0; /* useless if we are using 'external' select */ | 3769 | use_pipe = 0; /* useless if we are using 'external' select */ |
3768 | if (use_pipe) | 3770 | if (use_pipe) |
3769 | { | 3771 | { |
3770 | if (0 != MHD_pipe_ (daemon->wpipe)) | 3772 | if (0 != MHD_pipe_ (daemon->wpipe)) |
3771 | { | 3773 | { |
3772 | #ifdef HAVE_MESSAGES | 3774 | #ifdef HAVE_MESSAGES |