summaryrefslogtreecommitdiff
path: root/threadproc/win32
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2022-01-19 11:27:35 +0000
committerYann Ylavic <ylavic@apache.org>2022-01-19 11:27:35 +0000
commitea8d9ad623550b3ca466e272c8738002d2e0b088 (patch)
tree5a9aaee65ea66a401668f2169e88b15744ddd173 /threadproc/win32
parent7a52a7c060ebb42f6e83505755b49bc1e1acd183 (diff)
downloadapr-ea8d9ad623550b3ca466e272c8738002d2e0b088.tar.gz
apr_thread: Allocate the apr_thread_t struct on the thread's pool.
apr_thread_create() was allocating the created apr_thread_t on the given pool, which caused e.g. short-living threads to leak memory on that pool without a way to clear it (while some threads are still running). Change this by allocating the apr_thread_t on the thread's pool itself, which is safe in the implementations of all archs because none uses the apr_thread_t after the thread exits, and it's safe for the users provided they don't use the apr_thread_t for detached threads or for attached threads after the call to apr_thread_join(). These are hardly new requirements though. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897197 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'threadproc/win32')
-rw-r--r--threadproc/win32/thread.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/threadproc/win32/thread.c b/threadproc/win32/thread.c
index ae0c40794..02956c59f 100644
--- a/threadproc/win32/thread.c
+++ b/threadproc/win32/thread.c
@@ -95,12 +95,8 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
unsigned temp;
HANDLE handle;
apr_allocator_t *allocator;
+ apr_pool_t *p;
- (*new) = (apr_thread_t *)apr_pcalloc(pool, sizeof(apr_thread_t));
- if ((*new) == NULL) {
- return APR_ENOMEM;
- }
-
/* The thread can be detached anytime (from the creation or later with
* apr_thread_detach), so it needs its own pool and allocator to not
* depend on a parent pool which could be destroyed before the thread
@@ -111,15 +107,21 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
if (stat != APR_SUCCESS) {
return stat;
}
- stat = apr_pool_create_unmanaged_ex(&(*new)->pool,
- apr_pool_abort_get(pool),
+ stat = apr_pool_create_unmanaged_ex(&p, apr_pool_abort_get(pool),
allocator);
if (stat != APR_SUCCESS) {
apr_allocator_destroy(allocator);
return stat;
}
- apr_allocator_owner_set(allocator, (*new)->pool);
+ apr_allocator_owner_set(allocator, p);
+
+ (*new) = (apr_thread_t *)apr_pcalloc(p, sizeof(apr_thread_t));
+ if ((*new) == NULL) {
+ apr_pool_destroy(p);
+ return APR_ENOMEM;
+ }
+ (*new)->pool = p;
(*new)->data = data;
(*new)->func = func;
@@ -131,7 +133,7 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
(unsigned int (APR_THREAD_FUNC *)(void *))dummy_worker,
(*new), 0, &temp)) == 0) {
stat = APR_FROM_OS_ERROR(_doserrno);
- apr_pool_destroy((*new)->pool);
+ apr_pool_destroy(p);
return stat;
}
if (attr && attr->detach) {