apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Chris Knight <Christopher.D.Kni...@nasa.gov>
Subject allocator and using malloc alternatives
Date Tue, 18 May 2010 22:03:07 GMT

(First time poster [I think, I did submit a fix to psnprintf or something a number of years
ago], long time user and httpd module developer)

I propose the following change to the apr_allocator.h and apr_pools.c files. This allows you
to define a malloc/free alternative for apr_pools.c to use, if you so choose. This is useful
in a number of situations, particularly:

* provide pools on top of shm and mmap

* use a memory management test suite (efence, valgrind, etc.) - although many of these assume
you link against their malloc/free libraries, some provide alternate symbols that allow you
to mix-and-match

* use PHP's memory allocation for apr_pools, so that you honor PHP's memory limit mechanism
(a protection against DoS attacks)

* could probably be used in lieu of parent/child pools (create an allocator that back-ends
into a pool that backends into an allocator, ...), but I won't go there...:)

Here's the suggested patches, I'm certainly open to alternate naming, or different mechanisms
for doing the same thing. I haven't done any real testing of this to ensure that it works.
Only disadvantage is that it does mean you'll have one additional conditional to execute even
if you aren't using this capability, but the possibilities are great with the add.

< /**
<  * Redefines the function used by this apr_allocator to allocate a block of memory.
<  * @param allocator The allocator to set the memory allocation functions on
<  * @param alloc_fn The function for me to call when apr_allocator_alloc is called
<  * @param free_fn The function for me to call when apr_allocator_free is called
<  * @param opaque The opaque information to pass to these back-end functions
<  */
< typedef apr_memnode_t *(apr_allocator_alloc_fn_t)(apr_size_t size, void *opaque);
< typedef void(apr_allocator_free_fn_t)(apr_memnode_t *memnode, void *opaque);
< APR_DECLARE(apr_status_t) apr_allocator_set_fns(apr_allocator_t *allocator, apr_allocator_alloc_fn_t
*alloc_fn, apr_allocator_free_fn_t *free_fn, void *opaque);

<     // define these three if you'd like to use something other than malloc
<     apr_allocator_alloc_fn_t *alloc_fn;
<     apr_allocator_free_fn_t *free_fn;
<     void *alloc_opaque;
<     // if we have an alternate to malloc, call it
<     if (allocator->alloc_fn && (node = allocator->alloc_fn(size, allocator->alloc_opaque))
== NULL) return NULL;
<     // otherwise, just call malloc
< 	if (allocator->free_fn) allocator->free_fn(node, allocator->alloc_opaque);
<         else free(node);
>         free(node);
< APR_DECLARE(apr_status_t) apr_allocator_set_fns(apr_allocator_t *allocator, apr_allocator_alloc_fn_t
*alloc_fn, apr_allocator_free_fn_t *free_fn, void *opaque) {
<     allocator->alloc_fn = alloc_fn;
<     allocator->free_fn = free_fn;
<     allocator->alloc_opaque = opaque;
< }
View raw message