Bojan Smojver
Mon, 21 Jul 2008 23:12:53 -0700
On Mon, 2008-07-21 at 12:38 +0200, Mladen Turk wrote: > I still don't know how to solve that problem effectively, so > any ideas are welcome. A "volatile" pool idea... -- Bojan
Index: memory/unix/apr_pools.c
===================================================================
--- memory/unix/apr_pools.c (revision 678599)
+++ memory/unix/apr_pools.c (working copy)
@@ -503,6 +503,7 @@
#endif /* defined(NETWARE) */
cleanup_t *pre_cleanups;
cleanup_t *free_pre_cleanups;
+ int is_volatile;
};
#define SIZEOF_POOL_T APR_ALIGN_DEFAULT(sizeof(apr_pool_t))
@@ -523,6 +524,11 @@
static apr_file_t *file_stderr = NULL;
#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */
+#if APR_HAS_THREADS
+static apr_thread_mutex_t *volatile_mutex = NULL;
+#endif
+static apr_hash_t *volatile_pools = NULL;
+
/*
* Local functions
*/
@@ -588,6 +594,16 @@
apr_allocator_owner_set(global_allocator, global_pool);
+#if APR_HAS_THREADS
+ if ((rv = apr_thread_mutex_create(&volatile_mutex,
+ APR_THREAD_MUTEX_DEFAULT,
+ global_pool)) != APR_SUCCESS) {
+ return rv;
+ }
+#endif /* APR_HAS_THREADS */
+
+ volatile_pools = apr_hash_make(global_pool);
+
return APR_SUCCESS;
}
@@ -599,6 +615,8 @@
if (--apr_pools_initialized)
return;
+ apr_thread_mutex_destroy(volatile_mutex);
+
apr_pool_destroy(global_pool); /* This will also destroy the mutex */
global_pool = NULL;
@@ -759,6 +777,20 @@
apr_memnode_t *active;
apr_allocator_t *allocator;
+ if (pool->is_volatile) {
+#if APR_HAS_THREADS
+ if (volatile_mutex)
+ apr_thread_mutex_lock(volatile_mutex);
+#endif
+
+ apr_hash_set(volatile_pools, &pool, sizeof(pool), NULL);
+
+#if APR_HAS_THREADS
+ if (volatile_mutex)
+ apr_thread_mutex_unlock(volatile_mutex);
+#endif
+ }
+
/* Run pre destroy cleanups */
run_cleanups(&pool->pre_cleanups);
pool->pre_cleanups = NULL;
@@ -902,11 +934,41 @@
pool->ref = NULL;
}
+ pool->is_volatile = 0;
+
*newpool = pool;
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t)
+apr_pool_volatile_create_ex(apr_pool_t **newpool,
+ apr_pool_t *parent,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator)
+{
+ apr_status_t rv;
+
+ rv = apr_pool_create_ex(newpool, parent, abort_fn, allocator);
+
+ if (*newpool) {
+#if APR_HAS_THREADS
+ if (volatile_mutex)
+ apr_thread_mutex_lock(volatile_mutex);
+#endif
+
+ (*newpool)->is_volatile = 1;
+ apr_hash_set(volatile_pools, newpool, sizeof(*newpool), *newpool);
+
+#if APR_HAS_THREADS
+ if (volatile_mutex)
+ apr_thread_mutex_unlock(volatile_mutex);
+#endif
+ }
+
+ return rv;
+}
+
/* Deprecated. Renamed to apr_pool_create_unmanaged_ex
*/
APR_DECLARE(apr_status_t) apr_pool_create_core_ex(apr_pool_t **newpool,
@@ -1735,6 +1797,39 @@
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t)
+apr_pool_volatile_create_ex_debug(apr_pool_t **newpool,
+ apr_pool_t *parent,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator,
+ const char *file_line)
+{
+ apr_status_t rv;
+
+ rv = apr_pool_create_ex_debug(newpool, parent, abort_fn, allocator);
+
+ if (*newpool) {
+#if APR_HAS_THREADS
+ if (volatile_mutex)
+ apr_thread_mutex_lock(volatile_mutex);
+#endif
+
+ (*newpool)->is_volatile = 1;
+ apr_hash_set(volatile_pools, newpool, sizeof(*newpool), *newpool);
+
+#if APR_HAS_THREADS
+ if (volatile_mutex)
+ apr_thread_mutex_unlock(volatile_mutex);
+#endif
+ }
+
+#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)
+ apr_pool_log_event(pool, "CREATE", file_line, 1);
+#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */
+
+ return rv;
+}
+
APR_DECLARE(apr_status_t) apr_pool_create_core_ex_debug(apr_pool_t **newpool,
apr_abortfunc_t abort_fn,
apr_allocator_t *allocator,
@@ -2504,6 +2599,16 @@
return apr_pool_create_ex(newpool, parent, abort_fn, allocator);
}
+APR_DECLARE(apr_status_t)
+apr_pool_volatile_create_ex_debug(apr_pool_t **newpool,
+ apr_pool_t *parent,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator,
+ const char *file_line)
+{
+ return apr_pool_volatile_create_ex(newpool, parent, abort_fn, allocator);
+}
+
APR_DECLARE(apr_status_t) apr_pool_create_core_ex_debug(apr_pool_t **newpool,
apr_abortfunc_t abort_fn,
apr_allocator_t *allocator,
Index: include/apr_pools.h
===================================================================
--- include/apr_pools.h (revision 678599)
+++ include/apr_pools.h (working copy)
@@ -189,6 +189,22 @@
apr_allocator_t *allocator);
/**
+ * Create a new volatile pool.
+ * @param newpool The pool we have just created.
+ * @param parent The parent pool. If this is NULL, the new pool is a root
+ * pool. If it is non-NULL, the new pool will inherit all
+ * of its parent pool's attributes, except the apr_pool_t will
+ * be a sub-pool.
+ * @param abort_fn A function to use if the pool cannot allocate more memory.
+ * @param allocator The allocator to use with the new pool. If NULL the
+ * allocator of the parent pool will be used.
+ */
+APR_DECLARE(apr_status_t)
+apr_pool_volatile_create_ex(apr_pool_t **newpool,
+ apr_pool_t *parent,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator);
+/**
* Create a new pool.
* @deprecated @see apr_pool_create_unmanaged_ex.
*/
@@ -303,6 +319,28 @@
#endif
/**
+ * Create a new volatile pool.
+ * @param newpool The pool we have just created.
+ * @param parent The parent pool. If this is NULL, the new pool is a root
+ * pool. If it is non-NULL, the new pool will inherit all
+ * of its parent pool's attributes, except the apr_pool_t will
+ * be a sub-pool.
+ */
+#if defined(DOXYGEN)
+APR_DECLARE(apr_status_t) apr_pool_volatile_create(apr_pool_t **newpool,
+ apr_pool_t *parent);
+#else
+#if APR_POOL_DEBUG
+#define apr_pool_volatile_create(newpool, parent) \
+ apr_pool_volatile_create_ex_debug(newpool, parent, NULL, NULL, \
+ APR_POOL__FILE_LINE__)
+#else
+#define apr_pool_volatile_create(newpool, parent) \
+ apr_pool_volatile_create_ex(newpool, parent, NULL, NULL)
+#endif
+#endif
+
+/**
* Create a new pool.
* @param newpool The pool we have just created.
*/