1 /* libs/cutils/threads.c 2 ** 3 ** Copyright (C) 2007, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 #include <cutils/threads.h> 18 19 #ifdef HAVE_PTHREADS 20 void* thread_store_get( thread_store_t* store ) 21 { 22 const pthread_key_t k = store->tls; 23 24 if (!store->has_tls) 25 return NULL; 26 27 return pthread_getspecific( store->tls ); 28 } 29 30 extern void thread_store_set( thread_store_t* store, 31 void* value, 32 thread_store_destruct_t destroy) 33 { 34 pthread_mutex_lock( &store->lock ); 35 if (!store->has_tls) { 36 if (pthread_key_create( &store->tls, destroy) != 0) { 37 pthread_mutex_unlock(&store->lock); 38 return; 39 } 40 store->has_tls = 1; 41 } 42 pthread_mutex_unlock( &store->lock ); 43 44 pthread_setspecific( store->tls, value ); 45 } 46 47 #endif 48 49 #ifdef HAVE_WIN32_THREADS 50 void* thread_store_get( thread_store_t* store ) 51 { 52 if (!store->has_tls) 53 return NULL; 54 55 return (void*) TlsGetValue( store->tls ); 56 } 57 58 void thread_store_set( thread_store_t* store, 59 void* value, 60 thread_store_destruct_t destroy ) 61 { 62 /* XXX: can't use destructor on thread exit */ 63 if (!store->lock_init) { 64 store->lock_init = -1; 65 InitializeCriticalSection( &store->lock ); 66 store->lock_init = -2; 67 } else while (store->lock_init != -2) { 68 Sleep(10); /* 10ms */ 69 } 70 71 EnterCriticalSection( &store->lock ); 72 if (!store->has_tls) { 73 store->tls = TlsAlloc(); 74 if (store->tls == TLS_OUT_OF_INDEXES) { 75 LeaveCriticalSection( &store->lock ); 76 return; 77 } 78 store->has_tls = 1; 79 } 80 LeaveCriticalSection( &store->lock ); 81 82 TlsSetValue( store->tls, value ); 83 } 84 #endif 85