diff options
author | Yann Ylavic <ylavic@apache.org> | 2022-07-15 11:24:01 +0200 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2022-07-15 11:24:01 +0200 |
commit | 5382f96a3a0708c050ece38cf70ad8d6808b882c (patch) | |
tree | 16b7c99ca65d9c2b288ed7a501e1169672050105 /server/util.c | |
parent | Make pytest error whitelist a bit more explicit (diff) | |
download | apache2-5382f96a3a0708c050ece38cf70ad8d6808b882c.tar.xz apache2-5382f96a3a0708c050ece38cf70ad8d6808b882c.zip |
core: Apply ap_max_mem_free to created threads' pool allocator.
Since APR does not set the threshold above which the allocator of the thread's
starts returning its memory to the system, so set ap_max_mem_free from
ap_thread_create(), ap_thread_main_create() and ap_thread_current_create().
* include/httpd.h:
Provide our own ap_thread_create() in any case (but !APR_HAS_THREADS).
Simplify #ifdef-ery.
* server/util.c(thread_start, ap_thread_main_create, ap_thread_current_create):
Set ap_max_mem_free to the thread's pool allocator.
Simplify #ifdef-ery.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1902728 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/util.c')
-rw-r--r-- | server/util.c | 115 |
1 files changed, 62 insertions, 53 deletions
diff --git a/server/util.c b/server/util.c index cc0adbccd8..63c5132f2c 100644 --- a/server/util.c +++ b/server/util.c @@ -69,6 +69,7 @@ #endif #include "ap_mpm.h" +#include "mpm_common.h" /* for ap_max_mem_free */ /* A bunch of functions in util.c scan strings looking for certain characters. * To make that more efficient we encode a lookup table. The test_char_table @@ -3285,26 +3286,27 @@ AP_DECLARE(void *) ap_realloc(void *ptr, size_t size) #if APR_HAS_THREADS -#if APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) - -#define ap_thread_current_create apr_thread_current_create - -#else /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */ - -#if AP_HAS_THREAD_LOCAL +#if AP_HAS_THREAD_LOCAL && !APR_VERSION_AT_LEAST(1,8,0) +AP_THREAD_LOCAL static apr_thread_t *current_thread = NULL; +#endif struct thread_ctx { apr_thread_start_t func; void *data; }; -static AP_THREAD_LOCAL apr_thread_t *current_thread = NULL; - static void *APR_THREAD_FUNC thread_start(apr_thread_t *thread, void *data) { struct thread_ctx *ctx = data; + apr_pool_t *tp = apr_thread_pool_get(thread); + + /* Don't let the thread's pool allocator with no limits */ + apr_allocator_max_free_set(apr_pool_allocator_get(tp), + ap_max_mem_free); +#if AP_HAS_THREAD_LOCAL && !APR_VERSION_AT_LEAST(1,8,0) current_thread = thread; +#endif return ctx->func(thread, ctx->data); } @@ -3320,15 +3322,53 @@ AP_DECLARE(apr_status_t) ap_thread_create(apr_thread_t **thread, return apr_thread_create(thread, attr, thread_start, ctx, pool); } -#endif /* AP_HAS_THREAD_LOCAL */ +static apr_status_t main_thread_cleanup(void *arg) +{ + apr_thread_t *thd = arg; + apr_pool_destroy(apr_thread_pool_get(thd)); + return APR_SUCCESS; +} + +AP_DECLARE(apr_status_t) ap_thread_main_create(apr_thread_t **thread, + apr_pool_t *pool) +{ + apr_status_t rv; + apr_threadattr_t *attr = NULL; + + /* Create an apr_thread_t for the main child thread to set up its Thread + * Local Storage. Since it's detached and won't apr_thread_exit(), destroy + * its pool before exiting via a cleanup of the given pool. + */ + if ((rv = apr_threadattr_create(&attr, pool)) + || (rv = apr_threadattr_detach_set(attr, 1)) + || (rv = ap_thread_current_create(thread, attr, pool))) { + *thread = NULL; + return rv; + } + +#if APR_VERSION_AT_LEAST(1,8,0) + /* Don't let the thread's pool allocator with no limits */ + { + apr_pool_t *tp = apr_thread_pool_get(*thread); + apr_allocator_max_free_set(apr_pool_allocator_get(tp), + ap_max_mem_free); + } +#endif + + apr_pool_cleanup_register(pool, *thread, main_thread_cleanup, + apr_pool_cleanup_null); + return APR_SUCCESS; +} + +#if !APR_VERSION_AT_LEAST(1,8,0) AP_DECLARE(apr_status_t) ap_thread_current_create(apr_thread_t **current, apr_threadattr_t *attr, apr_pool_t *pool) { +#if AP_HAS_THREAD_LOCAL apr_status_t rv; - apr_abortfunc_t abort_fn = apr_pool_abort_get(pool); - apr_allocator_t *allocator; + apr_abortfunc_t abort_fn; apr_os_thread_t osthd; apr_pool_t *p; @@ -3337,18 +3377,15 @@ AP_DECLARE(apr_status_t) ap_thread_current_create(apr_thread_t **current, return APR_EEXIST; } - rv = apr_allocator_create(&allocator); - if (rv != APR_SUCCESS) { - if (abort_fn) - abort_fn(rv); - return rv; - } - rv = apr_pool_create_unmanaged_ex(&p, abort_fn, allocator); + abort_fn = (pool) ? apr_pool_abort_get(pool) : NULL; + rv = apr_pool_create_unmanaged_ex(&p, abort_fn, NULL); if (rv != APR_SUCCESS) { - apr_allocator_destroy(allocator); return rv; } - apr_allocator_owner_set(allocator, p); + + /* Don't let the thread's pool allocator with no limits */ + apr_allocator_max_free_set(apr_pool_allocator_get(p), + ap_max_mem_free); osthd = apr_os_thread_current(); rv = apr_os_thread_put(current, &osthd, p); @@ -3357,10 +3394,11 @@ AP_DECLARE(apr_status_t) ap_thread_current_create(apr_thread_t **current, return rv; } -#if AP_HAS_THREAD_LOCAL current_thread = *current; -#endif return APR_SUCCESS; +#else + return APR_ENOTIMPL; +#endif } AP_DECLARE(void) ap_thread_current_after_fork(void) @@ -3379,36 +3417,7 @@ AP_DECLARE(apr_thread_t *) ap_thread_current(void) #endif } -#endif /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */ - -static apr_status_t main_thread_cleanup(void *arg) -{ - apr_thread_t *thd = arg; - apr_pool_destroy(apr_thread_pool_get(thd)); - return APR_SUCCESS; -} - -AP_DECLARE(apr_status_t) ap_thread_main_create(apr_thread_t **thread, - apr_pool_t *pool) -{ - apr_status_t rv; - apr_threadattr_t *attr = NULL; - - /* Create an apr_thread_t for the main child thread to set up its Thread - * Local Storage. Since it's detached and won't apr_thread_exit(), destroy - * its pool before exiting via a cleanup of the given pool. - */ - if ((rv = apr_threadattr_create(&attr, pool)) - || (rv = apr_threadattr_detach_set(attr, 1)) - || (rv = ap_thread_current_create(thread, attr, pool))) { - *thread = NULL; - return rv; - } - - apr_pool_cleanup_register(pool, *thread, main_thread_cleanup, - apr_pool_cleanup_null); - return APR_SUCCESS; -} +#endif /* !APR_VERSION_AT_LEAST(1,8,0) */ #endif /* APR_HAS_THREADS */ |