diff options
Diffstat (limited to 'threadproc')
-rw-r--r-- | threadproc/beos/proc.c | 3 | ||||
-rw-r--r-- | threadproc/beos/thread.c | 93 | ||||
-rw-r--r-- | threadproc/netware/proc.c | 3 | ||||
-rw-r--r-- | threadproc/netware/thread.c | 114 | ||||
-rw-r--r-- | threadproc/os2/proc.c | 3 | ||||
-rw-r--r-- | threadproc/os2/thread.c | 91 | ||||
-rw-r--r-- | threadproc/unix/proc.c | 3 | ||||
-rw-r--r-- | threadproc/unix/thread.c | 96 | ||||
-rw-r--r-- | threadproc/win32/thread.c | 102 |
9 files changed, 442 insertions, 66 deletions
diff --git a/threadproc/beos/proc.c b/threadproc/beos/proc.c index e3698082f..cd6f9a250 100644 --- a/threadproc/beos/proc.c +++ b/threadproc/beos/proc.c @@ -170,6 +170,9 @@ APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *pool) } } +#if AP_HAS_THREAD_LOCAL + apr_thread_current_after_fork(); +#endif proc->pid = pid; proc->in = NULL; proc->out = NULL; diff --git a/threadproc/beos/thread.c b/threadproc/beos/thread.c index 988f8f4ff..f5752a81e 100644 --- a/threadproc/beos/thread.c +++ b/threadproc/beos/thread.c @@ -62,40 +62,51 @@ 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) { apr_thread_t *thd = (apr_thread_t*)opaque; void *ret; +#if APR_HAS_THREAD_LOCAL + current_thread = thd; +#endif + apr_pool_owner_set(thd->pool, 0); ret = thd->func(thd, thd->data); if (thd->detached) { apr_pool_destroy(thd->pool); } + return ret; } -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) { - int32 temp; 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; @@ -114,6 +125,22 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, apr_threadattr_t (*new)->exitval = -1; (*new)->detached = (attr && apr_threadattr_detach_get(attr) == APR_DETACH); + 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) +{ + int32 temp; + apr_status_t stat; + + stat = alloc_thread(new, attr, func, data, pool); + if (stat != APR_SUCCESS) { + return stat; + } + if (attr) temp = attr->attr; else @@ -126,13 +153,54 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, apr_threadattr_t /* Now we try to run it...*/ if (resume_thread((*new)->td) != B_NO_ERROR) { 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)->td = 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(void) { return find_thread(NULL); @@ -197,6 +265,10 @@ void apr_thread_yield() 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); } @@ -204,6 +276,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); } diff --git a/threadproc/netware/proc.c b/threadproc/netware/proc.c index f5d24b21b..1a6de7b7b 100644 --- a/threadproc/netware/proc.c +++ b/threadproc/netware/proc.c @@ -226,6 +226,9 @@ APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *pool) return errno; } else if (pid == 0) { +#if AP_HAS_THREAD_LOCAL + apr_thread_current_after_fork(); +#endif proc->pid = pid; proc->in = NULL; proc->out = NULL; diff --git a/threadproc/netware/thread.c b/threadproc/netware/thread.c index a661ef886..24122119a 100644 --- a/threadproc/netware/thread.c +++ b/threadproc/netware/thread.c @@ -64,43 +64,51 @@ 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) { apr_thread_t *thd = (apr_thread_t *)opaque; void *ret; +#if APR_HAS_THREAD_LOCAL + current_thread = thd; +#endif + apr_pool_owner_set(thd->pool, 0); ret = thd->func(thd, thd->data); if (thd->detached) { apr_pool_destroy(thd->pool); } + return ret; } -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; - unsigned long flags = NX_THR_BIND_CONTEXT; - size_t stack_size = APR_DEFAULT_STACK_SIZE; + 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; @@ -131,6 +139,24 @@ apr_status_t apr_thread_create(apr_thread_t **new, return APR_ENOMEM; } + 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; + unsigned long flags = NX_THR_BIND_CONTEXT; + size_t stack_size = APR_DEFAULT_STACK_SIZE; + + stat = alloc_thread(new, attr, func, data, pool); + if (stat != APR_SUCCESS) { + return stat; + } + /* An original stack size of 0 will allow NXCreateThread() to * assign a default system stack size. An original stack * size of less than 0 will assign the APR default stack size. @@ -139,11 +165,11 @@ apr_status_t apr_thread_create(apr_thread_t **new, if (attr && (attr->stack_size >= 0)) { stack_size = attr->stack_size; } - + if (attr && attr->detach) { flags |= NX_THR_DETACHED; } - + (*new)->ctx = NXContextAlloc( /* void(*start_routine)(void *arg) */ (void (*)(void *)) dummy_worker, /* void *arg */ (*new), @@ -151,7 +177,7 @@ apr_status_t apr_thread_create(apr_thread_t **new, /* size_t stackSize */ stack_size, /* unsigned long flags */ NX_CTX_NORMAL, /* int *error */ &stat); - + (void) NXContextSetName( /* NXContext_t ctx */ (*new)->ctx, /* const char *name */ (*new)->thread_name); @@ -162,13 +188,54 @@ apr_status_t apr_thread_create(apr_thread_t **new, /* NXThreadId_t *thread_id */ &(*new)->td); if (stat) { - 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)->td = 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_os_thread_t apr_os_thread_current() { return NXThreadGetId(); @@ -227,26 +294,21 @@ apr_status_t apr_thread_detach(apr_thread_t *thd) apr_status_t apr_thread_data_get(void **data, const char *key, apr_thread_t *thread) { - if (thread != NULL) { - return apr_pool_userdata_get(data, key, thread->pool); - } - else { - data = NULL; + if (thread == NULL) { + *data = NULL; return APR_ENOTHREAD; } + return apr_pool_userdata_get(data, key, thread->pool); } 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_pool_userdata_set(data, key, cleanup, thread->pool); - } - else { - data = NULL; + if (thread == NULL) { return APR_ENOTHREAD; } + return apr_pool_userdata_set(data, key, cleanup, thread->pool); } APR_DECLARE(apr_status_t) apr_os_thread_get(apr_os_thread_t **thethd, diff --git a/threadproc/os2/proc.c b/threadproc/os2/proc.c index cd7500129..beb100908 100644 --- a/threadproc/os2/proc.c +++ b/threadproc/os2/proc.c @@ -227,6 +227,9 @@ APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *pool) return errno; } else if (pid == 0) { +#if AP_HAS_THREAD_LOCAL + apr_thread_current_after_fork(); +#endif proc->pid = pid; proc->in = NULL; proc->out = NULL; 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); } diff --git a/threadproc/unix/proc.c b/threadproc/unix/proc.c index ed7a05fda..ad31c814f 100644 --- a/threadproc/unix/proc.c +++ b/threadproc/unix/proc.c @@ -234,6 +234,9 @@ APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *pool) return errno; } else if (pid == 0) { +#if AP_HAS_THREAD_LOCAL + apr_thread_current_after_fork(); +#endif proc->pid = getpid(); /* Do the work needed for children PRNG(s). */ diff --git a/threadproc/unix/thread.c b/threadproc/unix/thread.c index d1ae872c6..209fe7c86 100644 --- a/threadproc/unix/thread.c +++ b/threadproc/unix/thread.c @@ -136,42 +136,51 @@ APR_DECLARE(apr_status_t) apr_threadattr_guardsize_set(apr_threadattr_t *attr, #endif } +#if APR_HAS_THREAD_LOCAL +static APR_THREAD_LOCAL apr_thread_t *current_thread = NULL; +#endif + static void *dummy_worker(void *opaque) { apr_thread_t *thread = (apr_thread_t*)opaque; void *ret; +#if APR_HAS_THREAD_LOCAL + current_thread = thread; +#endif + apr_pool_owner_set(thread->pool, 0); ret = thread->func(thread, thread->data); if (thread->detached) { apr_pool_destroy(thread->pool); } + return ret; } -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; - pthread_attr_t *temp; + 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; @@ -194,6 +203,23 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, return APR_ENOMEM; } + 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; + pthread_attr_t *temp; + + stat = alloc_thread(new, attr, func, data, pool); + if (stat != APR_SUCCESS) { + return stat; + } + if (attr) temp = &attr->attr; else @@ -203,13 +229,54 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, #ifdef HAVE_ZOS_PTHREADS stat = errno; #endif - 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)->td = 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(void) { return pthread_self(); @@ -297,6 +364,10 @@ APR_DECLARE(void) apr_thread_yield(void) 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); } @@ -304,6 +375,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); } diff --git a/threadproc/win32/thread.c b/threadproc/win32/thread.c index 569268cd1..7e1c1a8be 100644 --- a/threadproc/win32/thread.c +++ b/threadproc/win32/thread.c @@ -72,43 +72,52 @@ 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) { apr_thread_t *thd = (apr_thread_t *)opaque; void *ret; +#if APR_HAS_THREAD_LOCAL + current_thread = thd; +#endif + TlsSetValue(tls_apr_thread, thd->td); apr_pool_owner_set(thd->pool, 0); ret = thd->func(thd, thd->data); if (!thd->td) { /* detached? */ apr_pool_destroy(thd->pool); } + return ret; } -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; - unsigned temp; - HANDLE handle; + 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; @@ -125,6 +134,23 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, (*new)->data = data; (*new)->func = func; + 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; + unsigned temp; + HANDLE handle; + + stat = alloc_thread(new, attr, func, data, pool); + if (stat != APR_SUCCESS) { + return stat; + } + /* Use 0 for default Thread Stack Size, because that will * default the stack to the same size as the calling thread. */ @@ -133,9 +159,10 @@ 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(p); + apr_pool_destroy((*new)->pool); return stat; } + if (attr && attr->detach) { CloseHandle(handle); } @@ -146,6 +173,49 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, 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; + } + + if (!(attr && attr->detach)) { + (*current)->td = 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(void) apr_thread_exit(apr_thread_t *thd, apr_status_t retval) { thd->exited = 1; @@ -153,6 +223,9 @@ APR_DECLARE(void) apr_thread_exit(apr_thread_t *thd, apr_status_t retval) if (!thd->td) { /* detached? */ apr_pool_destroy(thd->pool); } +#if APR_HAS_THREAD_LOCAL + current_thread = NULL; +#endif _endthreadex(0); } @@ -209,6 +282,10 @@ APR_DECLARE(void) apr_thread_yield() 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); } @@ -216,6 +293,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); } |