1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
18
#include "apr_portable.h"
19
#include "apr_strings.h"
20
#include "apr_arch_threadproc.h"
22
static int thread_count = 0;
24
apr_status_t apr_threadattr_create(apr_threadattr_t **new,
27
(*new) = (apr_threadattr_t *)apr_palloc(pool,
28
sizeof(apr_threadattr_t));
35
(*new)->stack_size = APR_DEFAULT_STACK_SIZE;
37
(*new)->thread_name = NULL;
41
apr_status_t apr_threadattr_detach_set(apr_threadattr_t *attr,apr_int32_t on)
47
apr_status_t apr_threadattr_detach_get(apr_threadattr_t *attr)
49
if (attr->detach == 1)
54
APR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
57
attr->stack_size = stacksize;
61
APR_DECLARE(apr_status_t) apr_threadattr_guardsize_set(apr_threadattr_t *attr,
67
static void *dummy_worker(void *opaque)
69
apr_thread_t *thd = (apr_thread_t *)opaque;
70
return thd->func(thd, thd->data);
73
apr_status_t apr_thread_create(apr_thread_t **new,
74
apr_threadattr_t *attr,
75
apr_thread_start_t func,
80
long flags = NX_THR_BIND_CONTEXT;
81
char threadName[NX_MAX_OBJECT_NAME_LEN+1];
82
size_t stack_size = APR_DEFAULT_STACK_SIZE;
84
if (attr && attr->thread_name) {
85
strncpy (threadName, attr->thread_name, NX_MAX_OBJECT_NAME_LEN);
88
sprintf(threadName, "APR_thread %04ld", ++thread_count);
91
/* An original stack size of 0 will allow NXCreateThread() to
92
* assign a default system stack size. An original stack
93
* size of less than 0 will assign the APR default stack size.
94
* anything else will be taken as is.
96
if (attr && (attr->stack_size >= 0)) {
97
stack_size = attr->stack_size;
100
(*new) = (apr_thread_t *)apr_palloc(pool, sizeof(apr_thread_t));
102
if ((*new) == NULL) {
109
(*new)->thread_name = (char*)apr_pstrdup(pool, threadName);
111
stat = apr_pool_create(&(*new)->pool, pool);
112
if (stat != APR_SUCCESS) {
116
if (attr && attr->detach) {
117
flags |= NX_THR_DETACHED;
120
(*new)->ctx = NXContextAlloc(
121
/* void(*start_routine)(void *arg)*/(void (*)(void *)) dummy_worker,
122
/* void *arg */ (*new),
123
/* int priority */ NX_PRIO_MED,
124
/* NXSize_t stackSize */ stack_size,
125
/* long flags */ NX_CTX_NORMAL,
126
/* int *error */ &stat);
129
stat = NXContextSetName(
130
/* NXContext_t ctx */ (*new)->ctx,
131
/* const char *name */ threadName);
133
stat = NXThreadCreate(
134
/* NXContext_t context */ (*new)->ctx,
135
/* long flags */ flags,
136
/* NXThreadId_t *thread_id */ &(*new)->td);
141
return(stat);// if error
144
apr_os_thread_t apr_os_thread_current()
146
return NXThreadGetId();
149
int apr_os_thread_equal(apr_os_thread_t tid1, apr_os_thread_t tid2)
151
return (tid1 == tid2);
154
void apr_thread_yield()
159
apr_status_t apr_thread_exit(apr_thread_t *thd,
162
thd->exitval = retval;
163
apr_pool_destroy(thd->pool);
168
apr_status_t apr_thread_join(apr_status_t *retval,
174
if ((stat = NXThreadJoin(thd->td, &dthr, NULL)) == 0) {
175
*retval = thd->exitval;
183
apr_status_t apr_thread_detach(apr_thread_t *thd)
188
apr_status_t apr_thread_data_get(void **data, const char *key,
189
apr_thread_t *thread)
191
if (thread != NULL) {
192
return apr_pool_userdata_get(data, key, thread->pool);
196
return APR_ENOTHREAD;
200
apr_status_t apr_thread_data_set(void *data, const char *key,
201
apr_status_t (*cleanup) (void *),
202
apr_thread_t *thread)
204
if (thread != NULL) {
205
return apr_pool_userdata_set(data, key, cleanup, thread->pool);
209
return APR_ENOTHREAD;
213
APR_DECLARE(apr_status_t) apr_os_thread_get(apr_os_thread_t **thethd,
217
return APR_ENOTHREAD;
219
*thethd = &(thd->td);
223
APR_DECLARE(apr_status_t) apr_os_thread_put(apr_thread_t **thd,
224
apr_os_thread_t *thethd,
230
if ((*thd) == NULL) {
231
(*thd) = (apr_thread_t *)apr_palloc(pool, sizeof(apr_thread_t));
234
(*thd)->td = *thethd;
238
APR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
241
(*control) = apr_pcalloc(p, sizeof(**control));
245
APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
248
if (!atomic_xchg(&control->value, 1)) {
254
APR_POOL_IMPLEMENT_ACCESSOR(thread)