19 #undef afw_pool_create_multithreaded
23 #define AFW_IMPLEMENTATION_ID "afw_pool_multithreaded"
27 #define IMPL_MULTITHREADED_LOCK_BEGIN(xctx) \
28 AFW_LOCK_BEGIN((xctx)->env->multithreaded_pool_lock)
31 #define IMPL_MULTITHREADED_LOCK_END \
36 #define IMPL_DEBUG_LEVEL_detail flag_index_debug_pool_detail
37 #define IMPL_DEBUG_LEVEL_minimal flag_index_debug_pool
39 #define IMPL_PRINT_DEBUG_INFO_Z(level,info_z) \
41 const afw_utf8_t *trace; \
42 if (afw_flag_is_active(xctx->env->IMPL_DEBUG_LEVEL_##level, xctx)) \
44 trace = afw_os_backtrace(0, -1, xctx); \
45 afw_debug_write_fz(NULL, source_z, xctx, \
46 "pool %" AFW_INTEGER_FMT " " \
48 ": before %" AFW_SIZE_T_FMT \
49 " refs %" AFW_INTEGER_FMT \
50 " parent %" AFW_INTEGER_FMT \
55 (self->bytes_allocated), \
56 (self->reference_count), \
57 (afw_integer_t)((self->parent) ? self->parent->pool_number : 0), \
58 (char *)((trace) ? "\n" : ""), \
59 (int)((trace) ? (int)trace->len : 0), \
60 (const char *)((trace) ? (const char *)trace->s : "") \
66 #define IMPL_PRINT_DEBUG_INFO_FZ(level,format_z,...) \
68 const afw_utf8_t *trace; \
69 if (afw_flag_is_active(xctx->env->IMPL_DEBUG_LEVEL_##level, xctx)) \
71 trace = afw_os_backtrace(0, -1, xctx); \
72 afw_debug_write_fz(NULL, source_z, xctx, \
73 "pool %" AFW_INTEGER_FMT " " \
75 ": before %" AFW_SIZE_T_FMT \
76 " refs %" AFW_INTEGER_FMT \
77 " parent %" AFW_INTEGER_FMT \
83 (self->bytes_allocated), \
84 (self->reference_count), \
85 (afw_integer_t)((self->parent) ? self->parent->pool_number : 0), \
86 (char *)((trace) ? "\n" : ""), \
87 (int)((trace) ? (int)trace->len : 0), \
88 (const char *)((trace) ? (const char *)trace->s : "") \
100 child->next_sibling = parent->first_child;
101 parent->first_child = child;
112 for (prev = NULL, sibling = parent->first_child;
114 prev = sibling, sibling = sibling->next_sibling)
116 if (sibling == child) {
118 parent->first_child = sibling->next_sibling;
121 prev->next_sibling = sibling->next_sibling;
142 apr_pool_create(&apr_p, (parent) ? parent->
apr_p : NULL);
150 self->pub.inf = &impl_afw_pool_inf;
152 self->reference_count = 1;
153 self->parent = parent;
159 impl_add_child(parent,
self, xctx);
168 afw_pool_internal_create_base_pool()
174 apr_pool_create(&apr_p, NULL);
180 self = apr_pcalloc(apr_p,
185 self->pub.inf = &impl_afw_pool_inf;
187 self->name = &afw_s_base;
188 self->pool_number = 1;
189 self->reference_count = 1;
203 if (parent != xctx->env->p &&
204 parent->inf != &impl_afw_pool_inf)
207 "Parent pool must be base or multithreaded", xctx);
211 parent = xctx->env->p;
230 IMPL_PRINT_DEBUG_INFO_FZ(minimal,
232 (self->parent) ? self->parent->pool_number : 0);
251 if (!instance)
return;
263 impl_afw_pool_add_reference(
270 if (!instance)
return;
281 impl_afw_pool_destroy(
291 if (!instance)
return;
298 e->cleanup(e->data, e->data2, instance, xctx);
306 for (child = self->first_child;
308 child = self->first_child)
315 impl_remove_child(self->parent,
self, xctx);
319 apr_pool_destroy(self->apr_p);
334 rv = apr_pool_create(&self->apr_p,
335 (self->parent) ? self->parent->apr_p : NULL);
336 if (rv != APR_SUCCESS) {
349 impl_afw_pool_calloc(
361 "Attempt to allocate memory for a size of 0",
365 IMPL_MULTITHREADED_LOCK_BEGIN(xctx) {
366 result = apr_pcalloc(self->apr_p, size);
367 self->bytes_allocated += size;
369 IMPL_MULTITHREADED_LOCK_END;
382 impl_afw_pool_malloc(
394 "Attempt to allocate memory for a size of 0",
398 IMPL_MULTITHREADED_LOCK_BEGIN(xctx) {
399 result = apr_palloc(self->apr_p, size);
400 self->bytes_allocated += size;
402 IMPL_MULTITHREADED_LOCK_END;
430 impl_afw_pool_register_cleanup_before(
447 e->cleanup = cleanup;
449 self->first_cleanup = e;
456 impl_afw_pool_deregister_cleanup(
468 e =
self->first_cleanup;
471 if (e->data == data && e->data2 == data2 && e->cleanup == cleanup) {
482 impl_afw_pool_release_debug(
490 IMPL_PRINT_DEBUG_INFO_Z(minimal,
"afw_pool_release");
499 impl_afw_pool_add_reference_debug(
507 IMPL_PRINT_DEBUG_INFO_Z(minimal,
"afw_pool_add_reference");
509 impl_afw_pool_add_reference(instance, xctx);
516 impl_afw_pool_destroy_debug(
524 IMPL_PRINT_DEBUG_INFO_Z(minimal,
"afw_pool_destroy");
526 impl_afw_pool_destroy(instance, xctx);
534 impl_afw_pool_calloc_debug(
543 IMPL_PRINT_DEBUG_INFO_FZ(detail,
547 return impl_afw_pool_calloc(instance, size, xctx);
554 impl_afw_pool_malloc_debug(
563 IMPL_PRINT_DEBUG_INFO_FZ(detail,
567 return impl_afw_pool_malloc(instance, size, xctx);
574 impl_afw_pool_free_debug(
584 IMPL_PRINT_DEBUG_INFO_FZ(detail,
596 impl_afw_pool_register_cleanup_before_debug(
607 IMPL_PRINT_DEBUG_INFO_FZ(minimal,
608 "afw_pool_register_cleanup_before %p %p",
611 impl_afw_pool_register_cleanup_before(instance, data, data2, cleanup, xctx);
618 impl_afw_pool_deregister_cleanup_debug(
629 IMPL_PRINT_DEBUG_INFO_FZ(minimal,
630 "afw_pool_deregister_cleanup_debug %p %p",
633 impl_afw_pool_deregister_cleanup(instance, data, data2, cleanup, xctx);
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
afw_integer_t afw_atomic_integer_decrement(AFW_ATOMIC afw_integer_t *mem)
Integer atomic decrement.
afw_integer_t afw_atomic_integer_increment(AFW_ATOMIC afw_integer_t *mem)
Integer atomic increment.
#define AFW_INTEGER_FMT
Format string specifier used for afw_integer_t.
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
apr_size_t afw_size_t
size_t.
void(* afw_pool_cleanup_function_p_t)(void *data, void *data2, const afw_pool_t *p, afw_xctx_t *xctx)
Typedef for pool cleanup functions.
#define AFW_SIZE_T_FMT
Format string specifier used for afw_size_t.
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
void impl_afw_pool_release(const afw_pool_t *instance, afw_xctx_t *xctx)
void impl_afw_pool_free(const afw_pool_t *instance, void *address, afw_size_t size, afw_xctx_t *xctx)
apr_pool_t * impl_afw_pool_get_apr_pool(const afw_pool_t *instance)
#define afw_pool_destroy(instance, xctx)
Call method destroy of interface afw_pool.
#define afw_pool_add_reference(instance, xctx)
Call method add_reference of interface afw_pool.
#define afw_pool_release(instance, xctx)
Call method release of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
afw_pool_create_multithreaded(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new multithreaded pool.
afw_pool_create_multithreaded_debug(const afw_pool_t *parent, afw_xctx_t *xctx, const afw_utf8_z_t *source_z)
Debug version of create a new multithreaded pool.
Struct for typedef afw_environment_t defined in afw_common.h.
Struct for registered cleanup functions.
afw_pool_cleanup_t * next_cleanup
Next cleanup function.
apr_pool_t * apr_p
Associated apr pool or NULL if it has not been created.
afw_integer_t pool_number
Unique number for pool.
Interface afw_pool public struct.
Interface afw_xctx public struct.