Mailing List Archive

svn commit: r1902728 - in /httpd/httpd/trunk: include/httpd.h server/util.c
Author: ylavic
Date: Fri Jul 15 09:24:01 2022
New Revision: 1902728

URL: http://svn.apache.org/viewvc?rev=1902728&view=rev
Log:
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.


Modified:
httpd/httpd/trunk/include/httpd.h
httpd/httpd/trunk/server/util.c

Modified: httpd/httpd/trunk/include/httpd.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/httpd.h?rev=1902728&r1=1902727&r2=1902728&view=diff
==============================================================================
--- httpd/httpd/trunk/include/httpd.h (original)
+++ httpd/httpd/trunk/include/httpd.h Fri Jul 15 09:24:01 2022
@@ -2571,27 +2571,35 @@ AP_DECLARE(void *) ap_realloc(void *ptr,

#if APR_HAS_THREADS

-#if APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL)
+/* apr_thread_create() wrapper that handles thread pool limits and
+ * ap_thread_current() eventually (if not handle by APR already).
+ */
+AP_DECLARE(apr_status_t) ap_thread_create(apr_thread_t **thread,
+ apr_threadattr_t *attr,
+ apr_thread_start_t func,
+ void *data, apr_pool_t *pool);
+
+/* Make the main() thread ap_thread_current()-able. */
+AP_DECLARE(apr_status_t) ap_thread_main_create(apr_thread_t **thread,
+ apr_pool_t *pool);
+
+#if APR_VERSION_AT_LEAST(1,8,0)

/**
- * APR 1.8+ implement those already.
+ * Use APR 1.8+ implementation.
*/
-#if APR_HAS_THREAD_LOCAL
-#define AP_HAS_THREAD_LOCAL 1
-#define AP_THREAD_LOCAL APR_THREAD_LOCAL
-#else
-#define AP_HAS_THREAD_LOCAL 0
+#if APR_HAS_THREAD_LOCAL && !defined(AP_NO_THREAD_LOCAL)
+#define AP_THREAD_LOCAL APR_THREAD_LOCAL
#endif
-#define ap_thread_create apr_thread_create
#define ap_thread_current apr_thread_current
#define ap_thread_current_create apr_thread_current_create
#define ap_thread_current_after_fork apr_thread_current_after_fork

-#else /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */
+#else /* APR_VERSION_AT_LEAST(1,8,0) */

-#ifndef AP_NO_THREAD_LOCAL
+#if !defined(AP_NO_THREAD_LOCAL)
/**
- * AP_THREAD_LOCAL keyword mapping the compiler's.
+ * AP_THREAD_LOCAL keyword aliases the compiler's.
*/
#if defined(__cplusplus) && __cplusplus >= 201103L
#define AP_THREAD_LOCAL thread_local
@@ -2604,18 +2612,7 @@ AP_DECLARE(void *) ap_realloc(void *ptr,
#elif defined(WIN32) && defined(_MSC_VER)
#define AP_THREAD_LOCAL __declspec(thread)
#endif
-#endif /* ndef AP_NO_THREAD_LOCAL */
-
-#ifndef AP_THREAD_LOCAL
-#define AP_HAS_THREAD_LOCAL 0
-#define ap_thread_create apr_thread_create
-#else /* AP_THREAD_LOCAL */
-#define AP_HAS_THREAD_LOCAL 1
-AP_DECLARE(apr_status_t) ap_thread_create(apr_thread_t **thread,
- apr_threadattr_t *attr,
- apr_thread_start_t func,
- void *data, apr_pool_t *pool);
-#endif /* AP_THREAD_LOCAL */
+#endif /* !defined(AP_NO_THREAD_LOCAL) */

AP_DECLARE(apr_status_t) ap_thread_current_create(apr_thread_t **current,
apr_threadattr_t *attr,
@@ -2623,16 +2620,15 @@ AP_DECLARE(apr_status_t) ap_thread_curre
AP_DECLARE(void) ap_thread_current_after_fork(void);
AP_DECLARE(apr_thread_t *) ap_thread_current(void);

-#endif /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */
-
-AP_DECLARE(apr_status_t) ap_thread_main_create(apr_thread_t **thread,
- apr_pool_t *pool);
+#endif /* APR_VERSION_AT_LEAST(1,8,0) */

-#else /* APR_HAS_THREADS */
+#endif /* APR_HAS_THREADS */

+#ifdef AP_THREAD_LOCAL
+#define AP_HAS_THREAD_LOCAL 1
+#else
#define AP_HAS_THREAD_LOCAL 0
-
-#endif /* APR_HAS_THREADS */
+#endif

/**
* Get server load params

Modified: httpd/httpd/trunk/server/util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util.c?rev=1902728&r1=1902727&r2=1902728&view=diff
==============================================================================
--- httpd/httpd/trunk/server/util.c (original)
+++ httpd/httpd/trunk/server/util.c Fri Jul 15 09:24:01 2022
@@ -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,

#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_creat
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_curre
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_curre
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_cur
#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 */