upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / threadproc / netware / thread.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "apr.h"
18 #include "apr_portable.h"
19 #include "apr_strings.h"
20 #include "apr_arch_threadproc.h"
21
22 static int thread_count = 0;
23
24 apr_status_t apr_threadattr_create(apr_threadattr_t **new,
25                                                 apr_pool_t *pool)
26 {
27     (*new) = (apr_threadattr_t *)apr_palloc(pool, 
28               sizeof(apr_threadattr_t));
29
30     if ((*new) == NULL) {
31         return APR_ENOMEM;
32     }
33
34     (*new)->pool = pool;
35     (*new)->stack_size = APR_DEFAULT_STACK_SIZE;
36     (*new)->detach = 0;
37     (*new)->thread_name = NULL;
38     return APR_SUCCESS;
39 }
40
41 apr_status_t apr_threadattr_detach_set(apr_threadattr_t *attr,apr_int32_t on)
42 {
43     attr->detach = on;
44         return APR_SUCCESS;   
45 }
46
47 apr_status_t apr_threadattr_detach_get(apr_threadattr_t *attr)
48 {
49     if (attr->detach == 1)
50         return APR_DETACH;
51     return APR_NOTDETACH;
52 }
53
54 APR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
55                                                        apr_size_t stacksize)
56 {
57     attr->stack_size = stacksize;
58     return APR_SUCCESS;
59 }
60
61 static void *dummy_worker(void *opaque)
62 {
63     apr_thread_t *thd = (apr_thread_t *)opaque;
64     return thd->func(thd, thd->data);
65 }
66
67 apr_status_t apr_thread_create(apr_thread_t **new,
68                                                                                         apr_threadattr_t *attr, 
69                                                         apr_thread_start_t func,
70                                                                                         void *data,
71                                                                                         apr_pool_t *pool)
72 {
73     apr_status_t stat;
74     long flags = NX_THR_BIND_CONTEXT;
75         char threadName[NX_MAX_OBJECT_NAME_LEN+1];
76     size_t stack_size = APR_DEFAULT_STACK_SIZE;
77
78     if (attr && attr->thread_name) {
79         strncpy (threadName, attr->thread_name, NX_MAX_OBJECT_NAME_LEN);
80     }
81     else {
82             sprintf(threadName, "APR_thread %04ld", ++thread_count);
83     }
84
85     /* An original stack size of 0 will allow NXCreateThread() to
86     *   assign a default system stack size.  An original stack
87     *   size of less than 0 will assign the APR default stack size.
88     *   anything else will be taken as is.
89     */
90     if (attr && (attr->stack_size >= 0)) {
91         stack_size = attr->stack_size;
92     }
93     
94     (*new) = (apr_thread_t *)apr_palloc(pool, sizeof(apr_thread_t));
95
96     if ((*new) == NULL) {
97         return APR_ENOMEM;
98     }
99     
100     (*new)->pool = pool;
101     (*new)->data = data;
102     (*new)->func = func;
103     (*new)->thread_name = (char*)apr_pstrdup(pool, threadName);
104     
105     stat = apr_pool_create(&(*new)->pool, pool);
106     if (stat != APR_SUCCESS) {
107         return stat;
108     }
109     
110     if (attr && attr->detach) {
111         flags |= NX_THR_DETACHED;
112     }
113     
114     (*new)->ctx = NXContextAlloc(
115         /* void(*start_routine)(void *arg)*/(void (*)(void *)) dummy_worker,
116         /* void *arg */                                                                            (*new),
117         /* int priority */                                                                         NX_PRIO_MED,
118         /* NXSize_t stackSize */                                                           stack_size,
119         /* long flags */                                                                           NX_CTX_NORMAL,
120         /* int *error */                                                                           &stat);
121                 
122                                                                            
123         stat = NXContextSetName(
124                         /* NXContext_t ctx */                   (*new)->ctx,
125                         /* const char *name */                  threadName);
126
127         stat = NXThreadCreate(
128                 /* NXContext_t context */               (*new)->ctx,
129                 /* long flags */                                flags,
130                 /* NXThreadId_t *thread_id */   &(*new)->td);
131
132     if(stat==0)
133         return APR_SUCCESS;
134         
135         return(stat);// if error    
136 }
137
138 apr_os_thread_t apr_os_thread_current()
139 {
140     return NXThreadGetId();
141 }
142
143 int apr_os_thread_equal(apr_os_thread_t tid1, apr_os_thread_t tid2)
144 {
145     return (tid1 == tid2);
146 }
147
148 void apr_thread_yield()
149 {
150     NXThreadYield();
151 }
152
153 apr_status_t apr_thread_exit(apr_thread_t *thd,
154                              apr_status_t retval)
155 {
156     thd->exitval = retval;
157     apr_pool_destroy(thd->pool);
158     NXThreadExit(NULL);
159     return APR_SUCCESS;
160 }
161
162 apr_status_t apr_thread_join(apr_status_t *retval,
163                                           apr_thread_t *thd)
164 {
165     apr_status_t  stat;    
166     NXThreadId_t dthr;
167
168     if ((stat = NXThreadJoin(thd->td, &dthr, NULL)) == 0) {
169         *retval = thd->exitval;
170         return APR_SUCCESS;
171     }
172     else {
173         return stat;
174     }
175 }
176
177 apr_status_t apr_thread_detach(apr_thread_t *thd)
178 {
179     return APR_SUCCESS;
180 }
181
182 apr_status_t apr_thread_data_get(void **data, const char *key,
183                                              apr_thread_t *thread)
184 {
185     if (thread != NULL) {
186             return apr_pool_userdata_get(data, key, thread->pool);
187     }
188     else {
189         data = NULL;
190         return APR_ENOTHREAD;
191     }
192 }
193
194 apr_status_t apr_thread_data_set(void *data, const char *key,
195                               apr_status_t (*cleanup) (void *),
196                               apr_thread_t *thread)
197 {
198     if (thread != NULL) {
199        return apr_pool_userdata_set(data, key, cleanup, thread->pool);
200     }
201     else {
202         data = NULL;
203         return APR_ENOTHREAD;
204     }
205 }
206
207 APR_DECLARE(apr_status_t) apr_os_thread_get(apr_os_thread_t **thethd,
208                                             apr_thread_t *thd)
209 {
210     if (thd == NULL) {
211         return APR_ENOTHREAD;
212     }
213     *thethd = &(thd->td);
214     return APR_SUCCESS;
215 }
216
217 APR_DECLARE(apr_status_t) apr_os_thread_put(apr_thread_t **thd,
218                                             apr_os_thread_t *thethd,
219                                             apr_pool_t *pool)
220 {
221     if (pool == NULL) {
222         return APR_ENOPOOL;
223     }
224     if ((*thd) == NULL) {
225         (*thd) = (apr_thread_t *)apr_palloc(pool, sizeof(apr_thread_t));
226         (*thd)->pool = pool;
227     }
228     (*thd)->td = *thethd;
229     return APR_SUCCESS;
230 }
231
232 APR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
233                                                apr_pool_t *p)
234 {
235     (*control) = apr_pcalloc(p, sizeof(**control));
236     return APR_SUCCESS;
237 }
238
239 APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
240                                           void (*func)(void))
241 {
242     if (!atomic_xchg(&control->value, 1)) {
243         func();
244     }
245     return APR_SUCCESS;
246 }
247
248 APR_POOL_IMPLEMENT_ACCESSOR(thread)
249
250