You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rp...@apache.org on 2007/12/11 14:27:22 UTC

svn commit: r603237 - in /httpd/httpd/trunk: CHANGES include/ap_mmn.h modules/proxy/mod_proxy.h modules/proxy/proxy_util.c

Author: rpluem
Date: Tue Dec 11 05:27:21 2007
New Revision: 603237

URL: http://svn.apache.org/viewvc?rev=603237&view=rev
Log:
* Use a separate subpool to manage the data for the socket and the connection
  member of the proxy_conn_rec struct as we destroy this data more frequently
  than other data in the proxy_conn_rec struct like hostname and addr (at least
  in the case where we have keepalive connections that timed out and were
  closed by the backend).
  This fixes a memory leak with short lived and broken connections.

PR: 44026

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/include/ap_mmn.h
    httpd/httpd/trunk/modules/proxy/mod_proxy.h
    httpd/httpd/trunk/modules/proxy/proxy_util.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=603237&r1=603236&r2=603237&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Tue Dec 11 05:27:21 2007
@@ -2,6 +2,9 @@
 Changes with Apache 2.3.0
 [ When backported to 2.2.x, remove entry from this file ]
 
+  *) mod_proxy: Lower memory consumption for short lived connections.
+     PR 44026. [Ruediger Pluem]
+
   *) core: Lower memory consumption of ap_r* functions by reusing the brigade
      instead of recreating it during each filter pass.
      [Stefan Fritsch <sf sfritsch.de>]

Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=603237&r1=603236&r2=603237&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Tue Dec 11 05:27:21 2007
@@ -144,6 +144,7 @@
  * 20071108.3 (2.3.0-dev)  Add API guarantee for adding connection filters
  *                         with non-NULL request_rec pointer (ap_add_*_filter*)
  * 20071108.4 (2.3.0-dev)  Add ap_proxy_ssl_connection_cleanup
+ * 20071108.5 (2.3.0-dev)  Add *scpool to proxy_conn_rec structure
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -151,7 +152,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20071108
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 4                    /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 5                    /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.h?rev=603237&r1=603236&r2=603237&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy.h Tue Dec 11 05:27:21 2007
@@ -230,7 +230,7 @@
     const char   *hostname;
     apr_port_t   port;
     int          is_ssl;
-    apr_pool_t   *pool;     /* Subpool used for creating socket */
+    apr_pool_t   *pool;     /* Subpool for hostname and addr data */
     apr_socket_t *sock;     /* Connection socket */
     apr_sockaddr_t *addr;   /* Preparsed remote address info */
     apr_uint32_t flags;     /* Conection flags */
@@ -240,6 +240,7 @@
 #if APR_HAS_THREADS
     int          inreslist; /* connection in apr_reslist? */
 #endif
+    apr_pool_t   *scpool;   /* Subpool used for socket and connection data */
 } proxy_conn_rec;
 
 typedef struct {

Modified: httpd/httpd/trunk/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/proxy_util.c?rev=603237&r1=603236&r2=603237&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/trunk/modules/proxy/proxy_util.c Tue Dec 11 05:27:21 2007
@@ -1600,12 +1600,13 @@
     if (conn->close) {
         apr_pool_t *p = conn->pool;
         if (conn->connection) {
-            apr_pool_cleanup_kill(conn->pool, conn, connection_cleanup);
+            apr_pool_cleanup_kill(p, conn, connection_cleanup);
         }
-        apr_pool_clear(conn->pool);
+        apr_pool_clear(p);
         memset(conn, 0, sizeof(proxy_conn_rec));
         conn->pool = p;
         conn->worker = worker;
+        apr_pool_create(&(conn->scpool), p);
     }
 #if APR_HAS_THREADS
     if (worker->hmax && worker->cp->res) {
@@ -1622,17 +1623,11 @@
     return APR_SUCCESS;
 }
 
-static apr_status_t socket_cleanup(proxy_conn_rec *conn)
+static void socket_cleanup(proxy_conn_rec *conn)
 {
-    if (conn->sock) {
-        apr_socket_close(conn->sock);
-        conn->sock = NULL;
-    }
-    if (conn->connection) {
-        apr_pool_cleanup_kill(conn->pool, conn, connection_cleanup);
-        conn->connection = NULL;
-    }
-    return APR_SUCCESS;
+    conn->sock = NULL;
+    conn->connection = NULL;
+    apr_pool_clear(conn->scpool);
 }
 
 PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn,
@@ -1675,6 +1670,7 @@
                                            apr_pool_t *pool)
 {
     apr_pool_t *ctx;
+    apr_pool_t *scpool;
     proxy_conn_rec *conn;
     proxy_worker *worker = (proxy_worker *)params;
 
@@ -1684,9 +1680,18 @@
      * when disconnecting from backend.
      */
     apr_pool_create(&ctx, pool);
+    /*
+     * Create another subpool that manages the data for the
+     * socket and the connection member of the proxy_conn_rec struct as we
+     * destroy this data more frequently than other data in the proxy_conn_rec
+     * struct like hostname and addr (at least in the case where we have
+     * keepalive connections that timed out).
+     */
+    apr_pool_create(&scpool, ctx);
     conn = apr_pcalloc(pool, sizeof(proxy_conn_rec));
 
     conn->pool   = ctx;
+    conn->scpool = scpool;
     conn->worker = worker;
 #if APR_HAS_THREADS
     conn->inreslist = 1;
@@ -2164,11 +2169,6 @@
         (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
 
     if (conn->sock) {
-        /*
-         * This increases the connection pool size
-         * but the number of dropped connections is
-         * relatively small compared to connection lifetime
-         */
         if (!(connected = is_socket_connected(conn->sock))) {
             socket_cleanup(conn);
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
@@ -2179,7 +2179,7 @@
     while (backend_addr && !connected) {
         if ((rv = apr_socket_create(&newsock, backend_addr->family,
                                 SOCK_STREAM, APR_PROTO_TCP,
-                                conn->pool)) != APR_SUCCESS) {
+                                conn->scpool)) != APR_SUCCESS) {
             loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
             ap_log_error(APLOG_MARK, loglevel, rv, s,
                          "proxy: %s: error creating fam %d socket for target %s",
@@ -2290,11 +2290,11 @@
         return OK;
     }
 
-    bucket_alloc = apr_bucket_alloc_create(conn->pool);
+    bucket_alloc = apr_bucket_alloc_create(conn->scpool);
     /*
      * The socket is now open, create a new backend server connection
      */
-    conn->connection = ap_run_create_connection(conn->pool, s, conn->sock,
+    conn->connection = ap_run_create_connection(conn->scpool, s, conn->sock,
                                                 0, NULL,
                                                 bucket_alloc);