You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by yl...@apache.org on 2017/03/28 07:39:47 UTC

svn commit: r1789061 - in /httpd/httpd/trunk: CHANGES server/listen.c

Author: ylavic
Date: Tue Mar 28 07:39:47 2017
New Revision: 1789061

URL: http://svn.apache.org/viewvc?rev=1789061&view=rev
Log:
core: Fix leak of duplicated listeners (socket descriptors) on restart
when ListenCoresBucketsRatio is configured (positive).


Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/server/listen.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1789061&r1=1789060&r2=1789061&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Tue Mar 28 07:39:47 2017
@@ -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]
 

Modified: httpd/httpd/trunk/server/listen.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/listen.c?rev=1789061&r1=1789060&r2=1789061&view=diff
==============================================================================
--- httpd/httpd/trunk/server/listen.c (original)
+++ httpd/httpd/trunk/server/listen.c Tue Mar 28 07:39:47 2017
@@ -516,6 +516,23 @@ static const char *alloc_listener(proces
 #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_li
 
     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(vo
 {
     old_listeners = ap_listeners;
     ap_listeners = NULL;
-    ap_listen_buckets = NULL;
-    ap_num_listen_buckets = 0;
     ap_listenbacklog = DEFAULT_LISTENBACKLOG;
     ap_listencbratio = 0;