diff options
Diffstat (limited to 'threadproc/os2/thread.c')
-rw-r--r-- | threadproc/os2/thread.c | 91 |
1 files changed, 82 insertions, 9 deletions
diff --git a/threadproc/os2/thread.c b/threadproc/os2/thread.c index 2891f0577..e0540188d 100644 --- a/threadproc/os2/thread.c +++ b/threadproc/os2/thread.c @@ -68,8 +68,16 @@ APR_DECLARE(apr_status_t) apr_threadattr_guardsize_set(apr_threadattr_t *attr, return APR_ENOTIMPL; } +#if APR_HAS_THREAD_LOCAL +static APR_THREAD_LOCAL apr_thread_t *current_thread = NULL; +#endif + static void dummy_worker(void *opaque) { +#if APR_HAS_THREAD_LOCAL + current_thread = thread; +#endif + apr_thread_t *thread = (apr_thread_t *)opaque; apr_pool_owner_set(thread->pool, 0); thread->exitval = thread->func(thread, thread->data); @@ -80,26 +88,29 @@ static void dummy_worker(void *opaque) -APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, apr_threadattr_t *attr, - apr_thread_start_t func, void *data, - apr_pool_t *pool) +static apr_status_t alloc_thread(apr_thread_t **new, + apr_threadattr_t *attr, + apr_thread_start_t func, void *data, + apr_pool_t *pool) { apr_status_t stat; + apr_abortfunc_t abort_fn = apr_pool_abort_get(pool); apr_allocator_t *allocator; apr_pool_t *p; - + /* 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 - * exits. The allocator needs no mutex obviously since the pool should + * exits. The allocator needs no mutex obviously since the pool should * not be used nor create children pools outside the thread. */ stat = apr_allocator_create(&allocator); if (stat != APR_SUCCESS) { + if (abort_fn) + abort_fn(stat); return stat; } - stat = apr_pool_create_unmanaged_ex(&p, apr_pool_abort_get(pool), - allocator); + stat = apr_pool_create_unmanaged_ex(&p, abort_fn, allocator); if (stat != APR_SUCCESS) { apr_allocator_destroy(allocator); return stat; @@ -124,19 +135,74 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, apr_threadattr_t } (*new)->attr = attr; - (*new)->tid = _beginthread(dummy_worker, NULL, + return APR_SUCCESS; +} + +APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, + apr_threadattr_t *attr, + apr_thread_start_t func, void *data, + apr_pool_t *pool) +{ + apr_status_t stat; + + stat = alloc_thread(new, attr, func, data, pool); + if (stat != APR_SUCCESS) { + return stat; + } + + (*new)->tid = _beginthread(dummy_worker, NULL, (*new)->attr->stacksize > 0 ? (*new)->attr->stacksize : APR_THREAD_STACKSIZE, (*new)); if ((*new)->tid < 0) { stat = errno; - apr_pool_destroy(p); + apr_pool_destroy((*new)->pool); + return stat; + } + + return APR_SUCCESS; +} + +APR_DECLARE(apr_status_t) apr_thread_current_create(apr_thread_t **current, + apr_threadattr_t *attr, + apr_pool_t *pool) +{ + apr_status_t stat; + + *current = apr_thread_current(); + if (*current) { + return APR_EEXIST; + } + + stat = alloc_thread(current, attr, NULL, NULL, pool); + if (stat != APR_SUCCESS) { + *current = NULL; return stat; } + (*current)->tid = apr_os_thread_current(); + +#if APR_HAS_THREAD_LOCAL + current_thread = *current; +#endif return APR_SUCCESS; } +APR_DECLARE(void) apr_thread_current_after_fork(void) +{ +#if APR_HAS_THREAD_LOCAL + current_thread = NULL; +#endif +} + +APR_DECLARE(apr_thread_t *) apr_thread_current(void) +{ +#if APR_HAS_THREAD_LOCAL + return current_thread; +#else + return NULL; +#endif +} APR_DECLARE(apr_os_thread_t) apr_os_thread_current() @@ -232,6 +298,10 @@ int apr_os_thread_equal(apr_os_thread_t tid1, apr_os_thread_t tid2) APR_DECLARE(apr_status_t) apr_thread_data_get(void **data, const char *key, apr_thread_t *thread) { + if (thread == NULL) { + *data = NULL; + return APR_ENOTHREAD; + } return apr_pool_userdata_get(data, key, thread->pool); } @@ -241,6 +311,9 @@ APR_DECLARE(apr_status_t) apr_thread_data_set(void *data, const char *key, apr_status_t (*cleanup) (void *), apr_thread_t *thread) { + if (thread == NULL) { + return APR_ENOTHREAD; + } return apr_pool_userdata_set(data, key, cleanup, thread->pool); } |