|
24 | 24 | #include "apr_arch_file_io.h"
|
25 | 25 | #include <stdlib.h>
|
26 | 26 |
|
| 27 | +/* Internal (from apr_pools.c) */ |
| 28 | +extern apr_status_t apr__pool_unmanage(apr_pool_t *pool); |
| 29 | + |
| 30 | + |
27 | 31 | APR_DECLARE(apr_status_t) apr_threadattr_create(apr_threadattr_t **new, apr_pool_t *pool)
|
28 | 32 | {
|
29 | 33 | (*new) = (apr_threadattr_t *)apr_palloc(pool, sizeof(apr_threadattr_t));
|
@@ -95,8 +99,40 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, apr_threadattr_t
|
95 | 99 | thread->attr = attr;
|
96 | 100 | thread->func = func;
|
97 | 101 | thread->data = data;
|
98 |
| - stat = apr_pool_create(&thread->pool, pool); |
99 |
| - |
| 102 | + |
| 103 | + if (attr && attr->attr & APR_THREADATTR_DETACHED) { |
| 104 | + stat = apr_pool_create_unmanaged_ex(&thread->pool, |
| 105 | + apr_pool_abort_get(pool), |
| 106 | + NULL); |
| 107 | + } |
| 108 | + else { |
| 109 | + /* The thread can be apr_thread_detach()ed later, so the pool needs |
| 110 | + * its own allocator to not depend on the parent pool which could be |
| 111 | + * destroyed before the thread exits. The allocator needs no mutex |
| 112 | + * obviously since the pool should not be used nor create children |
| 113 | + * pools outside the thread. |
| 114 | + */ |
| 115 | + apr_allocator_t *allocator; |
| 116 | + if (apr_allocator_create(&allocator) != APR_SUCCESS) { |
| 117 | + return APR_ENOMEM; |
| 118 | + } |
| 119 | + stat = apr_pool_create_ex(&thread->pool, pool, NULL, allocator); |
| 120 | + if (stat == APR_SUCCESS) { |
| 121 | + apr_thread_mutex_t *mutex; |
| 122 | + stat = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, |
| 123 | + thread->pool); |
| 124 | + if (stat == APR_SUCCESS) { |
| 125 | + apr_allocator_mutex_set(allocator, mutex); |
| 126 | + apr_allocator_owner_set(allocator, thread->pool); |
| 127 | + } |
| 128 | + else { |
| 129 | + apr_pool_destroy(thread->pool); |
| 130 | + } |
| 131 | + } |
| 132 | + if (stat != APR_SUCCESS) { |
| 133 | + apr_allocator_destroy(allocator); |
| 134 | + } |
| 135 | + } |
100 | 136 | if (stat != APR_SUCCESS) {
|
101 | 137 | return stat;
|
102 | 138 | }
|
@@ -172,7 +208,10 @@ APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd)
|
172 | 208 | return APR_EINVAL;
|
173 | 209 | }
|
174 | 210 |
|
| 211 | + /* Detach from the parent pool too */ |
| 212 | + apr__pool_unmanage(thd->pool); |
175 | 213 | thd->attr->attr |= APR_THREADATTR_DETACHED;
|
| 214 | + |
176 | 215 | return APR_SUCCESS;
|
177 | 216 | }
|
178 | 217 |
|
|
0 commit comments