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 24APR_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 40APR_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 52APR_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 65APR_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 80APR_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 86APR_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 93APR_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 100APR_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 */ 122APR_DECLARE(apr_status_t) apr_os_threadkey_get(void); 123 124APR_DECLARE(apr_status_t) apr_os_threadkey_get(void) 125{ 126 return APR_ENOTIMPL; 127} 128 129#endif 130