summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-03-15 19:31:42 +0000
committerChristian Grothoff <christian@grothoff.org>2016-03-15 19:31:42 +0000
commitc932ba77fde49a5c22374de96b8e56b17e746462 (patch)
treef6b0b5ad646b9089d3b7e8a95957e01cd14a0620
parentd3b17d3b19ad509e6e355677cc7fea73eb15c1b9 (diff)
fix unnecessary and potentially problematic use of eready DLL in thread-per-connection mode
-rw-r--r--ChangeLog4
-rw-r--r--src/include/microhttpd.h2
-rw-r--r--src/microhttpd/connection.c83
-rw-r--r--src/microhttpd/daemon.c54
4 files changed, 76 insertions, 67 deletions
diff --git a/ChangeLog b/ChangeLog
index c65582d7..402463eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Tue Mar 15 20:29:34 CET 2016
+ Do not use eready DLL data structure unless
+ we are actually using epoll(). -DD/CG
+
Fri Feb 5 20:43:11 CET 2016
Fixed testsuite compile warning on W32.
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;
* Current version of the library.
* 0x01093001 = 1.9.30-1.
*/
-#define MHD_VERSION 0x00094802
+#define MHD_VERSION 0x00094803
/**
* 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)
connection->state = MHD_CONNECTION_NORMAL_BODY_READY;
/* Buffering for flushable socket was already enabled*/
if (MHD_NO == socket_flush_possible (connection))
- socket_start_no_buffering (connection);
+ socket_start_no_buffering (connection);
break;
}
@@ -2737,7 +2737,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
connection->state = MHD_CONNECTION_CHUNKED_BODY_READY;
/* Buffering for flushable socket was already enabled */
if (MHD_NO == socket_flush_possible (connection))
- socket_start_no_buffering (connection);
+ socket_start_no_buffering (connection);
continue;
}
@@ -2860,45 +2860,48 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
}
MHD_connection_update_event_loop_info (connection);
#if EPOLL_SUPPORT
- switch (connection->event_loop_info)
+ if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
{
- case MHD_EVENT_LOOP_INFO_READ:
- if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
- (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
- (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
- {
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- connection);
- connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- break;
- case MHD_EVENT_LOOP_INFO_WRITE:
- if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
- (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
- (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
- {
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- connection);
- connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- break;
- case MHD_EVENT_LOOP_INFO_BLOCK:
- /* we should look at this connection again in the next iteration
- of the event loop, as we're waiting on the application */
- if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) &&
- (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) )
- {
- EDLL_insert (daemon->eready_head,
- daemon->eready_tail,
- connection);
- connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- break;
- case MHD_EVENT_LOOP_INFO_CLEANUP:
- /* This connection is finished, nothing left to do */
- break;
+ switch (connection->event_loop_info)
+ {
+ case MHD_EVENT_LOOP_INFO_READ:
+ if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ connection);
+ connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ break;
+ case MHD_EVENT_LOOP_INFO_WRITE:
+ if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ connection);
+ connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ break;
+ case MHD_EVENT_LOOP_INFO_BLOCK:
+ /* we should look at this connection again in the next iteration
+ of the event loop, as we're waiting on the application */
+ if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) &&
+ (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) )
+ {
+ EDLL_insert (daemon->eready_head,
+ daemon->eready_tail,
+ connection);
+ connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ break;
+ case MHD_EVENT_LOOP_INFO_CLEANUP:
+ /* This connection is finished, nothing left to do */
+ break;
+ }
}
return MHD_connection_epoll_update_ (connection);
#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 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2007-2014 Daniel Pittman and Christian Grothoff
+ Copyright (C) 2007-2016 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -2081,30 +2081,32 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
MHD_CONNECTION_NOTIFY_CLOSED);
MHD_ip_limit_del (daemon, pos->addr, pos->addr_len);
#if EPOLL_SUPPORT
- if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
- {
- EDLL_remove (daemon->eready_head,
- daemon->eready_tail,
- pos);
- pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
- }
- if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
- (MHD_INVALID_SOCKET != daemon->epoll_fd) &&
- (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
- {
- /* epoll documentation suggests that closing a FD
- automatically removes it from the epoll set; however,
- this is not true as if we fail to do manually remove it,
- we are still seeing an event for this fd in epoll,
- causing grief (use-after-free...) --- at least on my
- system. */
- if (0 != epoll_ctl (daemon->epoll_fd,
- EPOLL_CTL_DEL,
- pos->socket_fd,
- NULL))
- MHD_PANIC ("Failed to remove FD from epoll set\n");
- pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
- }
+ if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
+ {
+ if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
+ {
+ EDLL_remove (daemon->eready_head,
+ daemon->eready_tail,
+ pos);
+ pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
+ }
+ if ( (MHD_INVALID_SOCKET != daemon->epoll_fd) &&
+ (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
+ {
+ /* epoll documentation suggests that closing a FD
+ automatically removes it from the epoll set; however,
+ this is not true as if we fail to do manually remove it,
+ we are still seeing an event for this fd in epoll,
+ causing grief (use-after-free...) --- at least on my
+ system. */
+ if (0 != epoll_ctl (daemon->epoll_fd,
+ EPOLL_CTL_DEL,
+ pos->socket_fd,
+ NULL))
+ MHD_PANIC ("Failed to remove FD from epoll set\n");
+ pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
+ }
+ }
#endif
if (NULL != pos->response)
{
@@ -3766,7 +3768,7 @@ MHD_start_daemon_va (unsigned int flags,
if (0 == (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
use_pipe = 0; /* useless if we are using 'external' select */
if (use_pipe)
- {
+ {
if (0 != MHD_pipe_ (daemon->wpipe))
{
#ifdef HAVE_MESSAGES