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_arch_threadproc.h" 20 21 #if APR_HAS_THREADS 22 23 #if APR_HAVE_PTHREAD_H 24 APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key, 25 void (*dest)(void *), 26 apr_pool_t *pool) 27 { 28 (*key) = (apr_threadkey_t *)apr_pcalloc(pool, sizeof(apr_threadkey_t)); 29 30 if ((*key) == NULL) { 31 return APR_ENOMEM; 32 } 33 34 (*key)->pool = pool; 35 36 return pthread_key_create(&(*key)->key, dest); 37 38 } 39 40 APR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new, 41 apr_threadkey_t *key) 42 { 43 #ifdef PTHREAD_GETSPECIFIC_TAKES_TWO_ARGS 44 if (pthread_getspecific(key->key,new)) 45 *new = NULL; 46 #else 47 (*new) = pthread_getspecific(key->key); 48 #endif 49 return APR_SUCCESS; 50 } 51 52 APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv, 53 apr_threadkey_t *key) 54 { 55 apr_status_t stat; 56 57 if ((stat = pthread_setspecific(key->key, priv)) == 0) { 58 return APR_SUCCESS; 59 } 60 else { 61 return stat; 62 } 63 } 64 65 APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key) 66 { 67 #ifdef HAVE_PTHREAD_KEY_DELETE 68 apr_status_t stat; 69 70 if ((stat = pthread_key_delete(key->key)) == 0) { 71 return APR_SUCCESS; 72 } 73 74 return stat; 75 #else 76 return APR_ENOTIMPL; 77 #endif 78 } 79 80 APR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key, 81 apr_threadkey_t *threadkey) 82 { 83 return apr_pool_userdata_get(data, key, threadkey->pool); 84 } 85 86 APR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key, 87 apr_status_t (*cleanup)(void *), 88 apr_threadkey_t *threadkey) 89 { 90 return apr_pool_userdata_set(data, key, cleanup, threadkey->pool); 91 } 92 93 APR_DECLARE(apr_status_t) apr_os_threadkey_get(apr_os_threadkey_t *thekey, 94 apr_threadkey_t *key) 95 { 96 *thekey = key->key; 97 return APR_SUCCESS; 98 } 99 100 APR_DECLARE(apr_status_t) apr_os_threadkey_put(apr_threadkey_t **key, 101 apr_os_threadkey_t *thekey, 102 apr_pool_t *pool) 103 { 104 if (pool == NULL) { 105 return APR_ENOPOOL; 106 } 107 108 if ((*key) == NULL) { 109 (*key) = (apr_threadkey_t *)apr_pcalloc(pool, sizeof(apr_threadkey_t)); 110 (*key)->pool = pool; 111 } 112 113 (*key)->key = *thekey; 114 return APR_SUCCESS; 115 } 116 #endif /* APR_HAVE_PTHREAD_H */ 117 #endif /* APR_HAS_THREADS */ 118 119 #if !APR_HAS_THREADS 120 121 /* avoid warning for no prototype */ 122 APR_DECLARE(apr_status_t) apr_os_threadkey_get(void); 123 124 APR_DECLARE(apr_status_t) apr_os_threadkey_get(void) 125 { 126 return APR_ENOTIMPL; 127 } 128 129 #endif 130