Last active
December 16, 2015 15:48
-
-
Save scottjg/5458005 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/configure.ac b/configure.ac | |
index ad3b102..071d985 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -132,7 +132,7 @@ netbsd*) | |
;; | |
*linux*) | |
AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux kernel]) | |
- AC_DEFINE_UNQUOTED(HAVE_LISTEN_SHUTDOWN,1,[can use shutdown on listen sockets]) | |
+ #AC_DEFINE_UNQUOTED(HAVE_LISTEN_SHUTDOWN,1,[can use shutdown on listen sockets]) | |
AM_CONDITIONAL(HAVE_GNU_LD, true) | |
AM_CONDITIONAL(HAVE_W32, false) | |
;; | |
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c | |
index bdd9f87..c40dba5 100644 | |
--- a/src/daemon/daemon.c | |
+++ b/src/daemon/daemon.c | |
@@ -1352,7 +1352,7 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |
const fd_set *write_fd_set, | |
const fd_set *except_fd_set) | |
{ | |
- int ds; | |
+ int ds, tmp; | |
struct MHD_Connection *pos; | |
struct MHD_Connection *next; | |
@@ -1360,6 +1360,10 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |
if ( (-1 != (ds = daemon->socket_fd)) && | |
(FD_ISSET (ds, read_fd_set)) ) | |
MHD_accept_connection (daemon); | |
+ /* drain signaling pipe to avoid spinning select */ | |
+ if ( (-1 != daemon->wpipe[0]) && | |
+ (FD_ISSET(daemon->wpipe[0], read_fd_set)) ) | |
+ read(daemon->wpipe[0], &tmp, sizeof(tmp)); | |
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | |
{ | |
/* do not have a thread per connection, process all connections now */ | |
@@ -2692,6 +2696,51 @@ close_all_connections (struct MHD_Daemon *daemon) | |
MHD_cleanup_connections (daemon); | |
} | |
+/** | |
+ * Shutdown http daemon listening sockets. | |
+ * | |
+ * Allows clients to continue processing, but stops accepting connections | |
+ * | |
+ * @param daemon daemon to stop | |
+ */ | |
+void | |
+MHD_quiesce_daemon (struct MHD_Daemon *daemon) | |
+{ | |
+ int i, fd; | |
+ | |
+ if (NULL == daemon) | |
+ return; | |
+ | |
+ /* | |
+ * replace existing listening sockets with dummy sockets so event loops | |
+ * can continue operating normally. MHD_stop_daemon () will terminate the | |
+ * clients and finish cleanup. | |
+ */ | |
+ fd = daemon->socket_fd; | |
+ daemon->socket_fd = create_socket (PF_INET, SOCK_STREAM, 0); | |
+ LISTEN (daemon->socket_fd, 20); | |
+ if (NULL != daemon->worker_pool) | |
+ { | |
+ /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */ | |
+ for (i = 0; i < daemon->worker_pool_size; ++i) | |
+ { | |
+ daemon->worker_pool[i].socket_fd = daemon->socket_fd; | |
+ } | |
+ } | |
+ | |
+ if (-1 != daemon->wpipe[1]) | |
+ { | |
+ if (1 != WRITE (daemon->wpipe[1], "e", 1)) | |
+ MHD_PANIC ("failed to signal shutdownn via pipe"); | |
+ } | |
+#ifdef HAVE_LISTEN_SHUTDOWN | |
+ else | |
+ { | |
+ #error "HAVE_LISTEN_SHUTDOWN breaks rolling deploys, since shutdown() means forks can't call accept() on the same socket | |
+ } | |
+#endif | |
+} | |
+ | |
/** | |
* Shutdown an http daemon | |
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h | |
index 4da2619..672223d 100644 | |
--- a/src/include/microhttpd.h | |
+++ b/src/include/microhttpd.h | |
@@ -1111,6 +1111,17 @@ MHD_stop_daemon (struct MHD_Daemon *daemon); | |
/** | |
+ * Shutdown http daemon listening sockets. | |
+ * | |
+ * Allows clients to continue processing, but stops accepting connections | |
+ * | |
+ * @param daemon daemon to stop | |
+ */ | |
+void | |
+MHD_quiesce_daemon (struct MHD_Daemon *daemon); | |
+ | |
+ | |
+/** | |
* Add another client connection to the set of connections | |
* managed by MHD. This API is usually not needed (since | |
* MHD will accept inbound connections on the server socket). | |
diff --git a/src/include/plibc/plibc.h b/src/include/plibc/plibc.h | |
index 36698bf..bfc722f 100644 | |
--- a/src/include/plibc/plibc.h | |
+++ b/src/include/plibc/plibc.h | |
@@ -553,7 +553,11 @@ char *strcasestr(const char *haystack_start, const char *needle_start); | |
#define CHMOD(f, p) chmod(f, p) | |
#define FSTAT(h, b) fstat(h, b) | |
#define PLIBC_KILL(p, s) kill(p, s) | |
+#ifdef __linux__ | |
+ #define PIPE(h) pipe2(h, O_CLOEXEC) | |
+#else | |
#define PIPE(h) pipe(h) | |
+#endif | |
#define REMOVE(p) remove(p) | |
#define RENAME(o, n) rename(o, n) | |
#define STAT(p, b) stat(p, b) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment