]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
core: Fix leak of duplicated listeners (socket descriptors) on restart
authorYann Ylavic <ylavic@apache.org>
Tue, 28 Mar 2017 07:39:47 +0000 (07:39 +0000)
committerYann Ylavic <ylavic@apache.org>
Tue, 28 Mar 2017 07:39:47 +0000 (07:39 +0000)
when ListenCoresBucketsRatio is configured (positive).

[Reverted by r1789069]

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1789061 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/listen.c

diff --git a/CHANGES b/CHANGES
index 16d64dd962ac089da06b23daaa3185e385f4ec3a..bc3cd96c65fc550351e7d9f2c033a7a373820961 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) core: Fix leak of duplicated listeners (socket descriptors) on restart
+     when ListenCoresBucketsRatio is configured (positive).  [Yann Ylavic]
+
   *) mod_http2: input buffering and dynamic flow windows for increased 
      throughput. [Stefan Eissing]
 
index 9989b8074865633ef02e79b594ebdfe9e483abab..fc8ec7f03b66bab92d43795e0aa30c750c7c17a0 100644 (file)
@@ -516,6 +516,23 @@ static const char *alloc_listener(process_rec *process, char *addr,
 #define IS_IN6ADDR_ANY(addr) ((addr)->family == APR_INET6 \
                               && IN6_IS_ADDR_UNSPECIFIED(&(addr)->sa.sin6.sin6_addr))
 
+static apr_status_t ap_close_duplicated_listeners(void *nil)
+{
+    int i;
+
+    /* Start from index 1 since either ap_duplicate_listeners()
+     * was called and ap_listen_buckets[0] == ap_listeners, or
+     * it wasn't and ap_num_listen_buckets == 0.
+     */
+    for (i = 1; i < ap_num_listen_buckets; i++) {
+        ap_close_listeners_ex(ap_listen_buckets[i]);
+    }
+    ap_num_listen_buckets = 0;
+    ap_listen_buckets = NULL;
+
+    return APR_SUCCESS;
+}
+
 /**
  * Create, open, listen, and bind all sockets.
  * @param process The process record for the currently running server
@@ -867,22 +884,15 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
 
     ap_listen_buckets = *buckets;
     ap_num_listen_buckets = *num_buckets;
+    apr_pool_cleanup_register(p, NULL, ap_close_duplicated_listeners,
+                              apr_pool_cleanup_null);
     return APR_SUCCESS;
 }
 
 AP_DECLARE_NONSTD(void) ap_close_listeners(void)
 {
-    int i;
-
     ap_close_listeners_ex(ap_listeners);
-
-    /* Start from index 1 since either ap_duplicate_listeners()
-     * was called and ap_listen_buckets[0] == ap_listeners, or
-     * it wasn't and ap_num_listen_buckets == 0.
-     */
-    for (i = 1; i < ap_num_listen_buckets; i++) {
-        ap_close_listeners_ex(ap_listen_buckets[i]);
-    }
+    ap_close_duplicated_listeners(NULL);
 }
 
 AP_DECLARE_NONSTD(void) ap_close_listeners_ex(ap_listen_rec *listeners)
@@ -915,8 +925,6 @@ AP_DECLARE(void) ap_listen_pre_config(void)
 {
     old_listeners = ap_listeners;
     ap_listeners = NULL;
-    ap_listen_buckets = NULL;
-    ap_num_listen_buckets = 0;
     ap_listenbacklog = DEFAULT_LISTENBACKLOG;
     ap_listencbratio = 0;