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_arch_threadproc.h" 18 19static struct beos_key key_table[BEOS_MAX_DATAKEYS]; 20static struct beos_private_data *beos_data[BEOS_MAX_DATAKEYS]; 21static sem_id lock; 22 23APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key, 24 void (*dest)(void *), apr_pool_t *pool) 25{ 26 (*key) = (apr_threadkey_t *)apr_palloc(pool, sizeof(apr_threadkey_t)); 27 if ((*key) == NULL) { 28 return APR_ENOMEM; 29 } 30 31 (*key)->pool = pool; 32 33 acquire_sem(lock); 34 for ((*key)->key=0; (*key)->key < BEOS_MAX_DATAKEYS; (*key)->key++){ 35 if (key_table[(*key)->key].assigned == 0){ 36 key_table[(*key)->key].assigned = 1; 37 key_table[(*key)->key].destructor = dest; 38 release_sem(lock); 39 return APR_SUCCESS; 40 } 41 42 } 43 release_sem(lock); 44 return APR_ENOMEM; 45} 46 47APR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new, apr_threadkey_t *key) 48{ 49 thread_id tid; 50 int i, index=0; 51 tid = find_thread(NULL); 52 for (i=0;i<BEOS_MAX_DATAKEYS;i++){ 53 if (beos_data[i]->data){ 54 /* it's been used */ 55 if (beos_data[i]->td == tid){ 56 index = i; 57 } 58 } 59 } 60 if (index == 0){ 61 /* no storage for thread so we can't get anything... */ 62 return APR_ENOMEM; 63 } 64 65 if ((key->key < BEOS_MAX_DATAKEYS) && (key_table)){ 66 acquire_sem(key_table[key->key].lock); 67 if (key_table[key->key].count){ 68 (*new) = (void*)beos_data[index]->data[key->key]; 69 } else { 70 (*new) = NULL; 71 } 72 release_sem(key_table[key->key].lock); 73 } else { 74 (*new) = NULL; 75 } 76 return APR_SUCCESS; 77} 78 79APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv, apr_threadkey_t *key) 80{ 81 thread_id tid; 82 int i,index = 0, ret = 0; 83 84 tid = find_thread(NULL); 85 for (i=0; i < BEOS_MAX_DATAKEYS; i++){ 86 if (beos_data[i]->data){ 87 if (beos_data[i]->td == tid){index = i;} 88 } 89 } 90 if (index==0){ 91 /* not yet been allocated */ 92 for (i=0; i< BEOS_MAX_DATAKEYS; i++){ 93 if (! beos_data[i]->data){ 94 /* we'll take this one... */ 95 index = i; 96 beos_data[i]->data = (const void **)malloc(sizeof(void *) * BEOS_MAX_DATAKEYS); 97 memset((void *)beos_data[i]->data, 0, sizeof(void *) * BEOS_MAX_DATAKEYS); 98 beos_data[i]->count = (int)malloc(sizeof(int)); 99 beos_data[i]->td = (thread_id)malloc(sizeof(thread_id)); 100 beos_data[i]->td = tid; 101 } 102 } 103 } 104 if (index == 0){ 105 /* we're out of luck.. */ 106 return APR_ENOMEM; 107 } 108 if ((key->key < BEOS_MAX_DATAKEYS) && (key_table)){ 109 acquire_sem(key_table[key->key].lock); 110 if (key_table[key->key].count){ 111 if (beos_data[index]->data[key->key] == NULL){ 112 if (priv != NULL){ 113 beos_data[index]->count++; 114 key_table[key->key].count++; 115 } 116 } else { 117 if (priv == NULL){ 118 beos_data[index]->count--; 119 key_table[key->key].count--; 120 } 121 } 122 beos_data[index]->data[key->key] = priv; 123 ret = 1; 124 } else { 125 ret = 0; 126 } 127 release_sem(key_table[key->key].lock); 128 } 129 if (ret) 130 return APR_SUCCESS; 131 return APR_ENOMEM; 132} 133 134APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key) 135{ 136 if (key->key < BEOS_MAX_DATAKEYS){ 137 acquire_sem(key_table[key->key].lock); 138 if (key_table[key->key].count == 1){ 139 key_table[key->key].destructor = NULL; 140 key_table[key->key].count = 0; 141 } 142 release_sem(key_table[key->key].lock); 143 } else { 144 return APR_ENOMEM; 145 } 146 return APR_SUCCESS; 147} 148 149APR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key, 150 apr_threadkey_t *threadkey) 151{ 152 return apr_pool_userdata_get(data, key, threadkey->pool); 153} 154 155APR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key, 156 apr_status_t (*cleanup) (void *), 157 apr_threadkey_t *threadkey) 158{ 159 return apr_pool_userdata_set(data, key, cleanup, threadkey->pool); 160} 161 162APR_DECLARE(apr_status_t) apr_os_threadkey_get(apr_os_threadkey_t *thekey, apr_threadkey_t *key) 163{ 164 *thekey = key->key; 165 return APR_SUCCESS; 166} 167 168APR_DECLARE(apr_status_t) apr_os_threadkey_put(apr_threadkey_t **key, 169 apr_os_threadkey_t *thekey, apr_pool_t *pool) 170{ 171 if (pool == NULL) { 172 return APR_ENOPOOL; 173 } 174 if ((*key) == NULL) { 175 (*key) = (apr_threadkey_t *)apr_pcalloc(pool, sizeof(apr_threadkey_t)); 176 (*key)->pool = pool; 177 } 178 (*key)->key = *thekey; 179 return APR_SUCCESS; 180} 181