dev  

Re: svn commit: r677505 - /apr/apr-util/trunk/misc/apr_reslist.c

Bojan Smojver
Fri, 18 Jul 2008 16:32:57 -0700

On Sat, 2008-07-19 at 09:08 +1000, Bojan Smojver wrote:

> This should be better.

Third time's the charm? I keep forgetting that by the time destructor is
called, pool may be dead and buried already...

-- 
Bojan
Index: memcache/apr_memcache.c
===================================================================
--- memcache/apr_memcache.c	(revision 677819)
+++ memcache/apr_memcache.c	(working copy)
@@ -295,7 +295,28 @@
     return rv;
 }
 
+static apr_status_t conn_clean(void *data)
+{
+    apr_memcache_conn_t *conn = data;
+    struct iovec vec[2];
+    apr_size_t written;
 
+    /* send a quit message to the memcached server to be nice about it. */
+    vec[0].iov_base = MC_QUIT;
+    vec[0].iov_len = MC_QUIT_LEN;
+
+    vec[1].iov_base = MC_EOL;
+    vec[1].iov_len = MC_EOL_LEN;
+    
+    /* Return values not checked, since we just want to make it go away. */
+    apr_socket_sendv(conn->sock, vec, 2, &written);
+    apr_socket_close(conn->sock);
+
+    conn->p = NULL; /* so that destructor does not destroy the pool again */
+
+    return APR_SUCCESS;
+}
+
 static apr_status_t
 mc_conn_construct(void **conn_, void *params, apr_pool_t *pool)
 {
@@ -310,7 +331,7 @@
         return rv;
     }
 
-    conn = apr_palloc(np, sizeof( apr_memcache_conn_t ));
+    conn = malloc(sizeof( apr_memcache_conn_t )); /* non-pool space! */
 
     conn->p = np;
 
@@ -334,8 +355,10 @@
     rv = conn_connect(conn);
     if (rv != APR_SUCCESS) {
         apr_pool_destroy(np);
+        free(conn);
     }
     else {
+        apr_pool_cleanup_register(np, conn, conn_clean, apr_pool_cleanup_null);
         *conn_ = conn;
     }
     
@@ -346,20 +369,13 @@
 mc_conn_destruct(void *conn_, void *params, apr_pool_t *pool)
 {
     apr_memcache_conn_t *conn = (apr_memcache_conn_t*)conn_;
-    struct iovec vec[2];
-    apr_size_t written;
     
-    /* send a quit message to the memcached server to be nice about it. */
-    vec[0].iov_base = MC_QUIT;
-    vec[0].iov_len = MC_QUIT_LEN;
+    if (conn->p) {
+        apr_pool_destroy(conn->p);
+    }
 
-    vec[1].iov_base = MC_EOL;
-    vec[1].iov_len = MC_EOL_LEN;
+    free(conn); /* free non-pool space */
     
-    /* Return values not checked, since we just want to make it go away. */
-    apr_socket_sendv(conn->sock, vec, 2, &written);
-    apr_socket_close(conn->sock);
-    
     return APR_SUCCESS;
 }