Home | History | Annotate | Download | only in libcutils
      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