blob: ca600b3b1a5196854be25da5b9892cc1af42dc51 [file] [log] [blame]
Mark Salyzyn12717162014-04-29 15:49:14 -07001/*
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002** Copyright (C) 2007, The Android Open Source Project
3**
Yabin Cui4a6e5a32015-01-26 19:48:54 -08004** Licensed under the Apache License, Version 2.0 (the "License");
5** you may not use this file except in compliance with the License.
6** You may obtain a copy of the License at
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08007**
Yabin Cui4a6e5a32015-01-26 19:48:54 -08008** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08009**
Yabin Cui4a6e5a32015-01-26 19:48:54 -080010** 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
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080014** limitations under the License.
15*/
Mark Salyzyn12717162014-04-29 15:49:14 -070016
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080017#include <cutils/threads.h>
18
Yabin Cui4a6e5a32015-01-26 19:48:54 -080019#if !defined(_WIN32)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080020void* thread_store_get( thread_store_t* store )
21{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080022 if (!store->has_tls)
23 return NULL;
24
25 return pthread_getspecific( store->tls );
26}
Yabin Cui4a6e5a32015-01-26 19:48:54 -080027
28extern void thread_store_set( thread_store_t* store,
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080029 void* value,
30 thread_store_destruct_t destroy)
31{
32 pthread_mutex_lock( &store->lock );
33 if (!store->has_tls) {
34 if (pthread_key_create( &store->tls, destroy) != 0) {
35 pthread_mutex_unlock(&store->lock);
36 return;
37 }
38 store->has_tls = 1;
39 }
40 pthread_mutex_unlock( &store->lock );
41
42 pthread_setspecific( store->tls, value );
43}
44
Yabin Cui4a6e5a32015-01-26 19:48:54 -080045#else /* !defined(_WIN32) */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080046void* thread_store_get( thread_store_t* store )
47{
48 if (!store->has_tls)
49 return NULL;
Yabin Cui4a6e5a32015-01-26 19:48:54 -080050
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080051 return (void*) TlsGetValue( store->tls );
52}
53
54void thread_store_set( thread_store_t* store,
55 void* value,
56 thread_store_destruct_t destroy )
57{
58 /* XXX: can't use destructor on thread exit */
59 if (!store->lock_init) {
60 store->lock_init = -1;
61 InitializeCriticalSection( &store->lock );
62 store->lock_init = -2;
63 } else while (store->lock_init != -2) {
64 Sleep(10); /* 10ms */
65 }
Yabin Cui4a6e5a32015-01-26 19:48:54 -080066
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080067 EnterCriticalSection( &store->lock );
68 if (!store->has_tls) {
69 store->tls = TlsAlloc();
70 if (store->tls == TLS_OUT_OF_INDEXES) {
71 LeaveCriticalSection( &store->lock );
72 return;
73 }
74 store->has_tls = 1;
75 }
76 LeaveCriticalSection( &store->lock );
Yabin Cui4a6e5a32015-01-26 19:48:54 -080077
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080078 TlsSetValue( store->tls, value );
79}
Yabin Cui4a6e5a32015-01-26 19:48:54 -080080#endif /* !defined(_WIN32) */