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#include "apr_thread_proc.h"
19#include "apr_general.h"
20#include "apr_lib.h"
21#include "apr_errno.h"
22#include "apr_portable.h"
23
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_palloc(pool, sizeof(apr_threadkey_t));
29    if ((*key) == NULL) {
30        return APR_ENOMEM;
31    }
32
33    (*key)->pool = pool;
34
35    if (((*key)->key = TlsAlloc()) != 0xFFFFFFFF) {
36        return APR_SUCCESS;
37    }
38    return apr_get_os_error();
39}
40
41APR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new,
42                                                 apr_threadkey_t *key)
43{
44    if (((*new) = TlsGetValue(key->key))) {
45        return APR_SUCCESS;
46    }
47    return apr_get_os_error();
48}
49
50APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv,
51                                                 apr_threadkey_t *key)
52{
53    if (TlsSetValue(key->key, priv)) {
54        return APR_SUCCESS;
55    }
56    return apr_get_os_error();
57}
58
59APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key)
60{
61    if (TlsFree(key->key)) {
62        return APR_SUCCESS;
63    }
64    return apr_get_os_error();
65}
66
67APR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key,
68                                                apr_threadkey_t *threadkey)
69{
70    return apr_pool_userdata_get(data, key, threadkey->pool);
71}
72
73APR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key,
74                                                apr_status_t (*cleanup)(void *),
75                                                apr_threadkey_t *threadkey)
76{
77    return apr_pool_userdata_set(data, key, cleanup, threadkey->pool);
78}
79
80APR_DECLARE(apr_status_t) apr_os_threadkey_get(apr_os_threadkey_t *thekey,
81                                               apr_threadkey_t *key)
82{
83    *thekey = key->key;
84    return APR_SUCCESS;
85}
86
87APR_DECLARE(apr_status_t) apr_os_threadkey_put(apr_threadkey_t **key,
88                                               apr_os_threadkey_t *thekey,
89                                               apr_pool_t *pool)
90{
91    if (pool == NULL) {
92        return APR_ENOPOOL;
93    }
94    if ((*key) == NULL) {
95        (*key) = (apr_threadkey_t *)apr_palloc(pool, sizeof(apr_threadkey_t));
96        (*key)->pool = pool;
97    }
98    (*key)->key = *thekey;
99    return APR_SUCCESS;
100}
101
102