Home | History | Annotate | Download | only in libcutils
      1 /*
      2 ** Copyright (C) 2007, The Android Open Source Project
      3 **
      4 ** 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
      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 <cutils/threads.h>
     18 
     19 #ifdef HAVE_PTHREADS
     20 void*  thread_store_get( thread_store_t*  store )
     21 {
     22     if (!store->has_tls)
     23         return NULL;
     24 
     25     return pthread_getspecific( store->tls );
     26 }
     27 
     28 extern void   thread_store_set( thread_store_t*          store,
     29                                 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 
     45 #endif
     46 
     47 #ifdef HAVE_WIN32_THREADS
     48 void*  thread_store_get( thread_store_t*  store )
     49 {
     50     if (!store->has_tls)
     51         return NULL;
     52 
     53     return (void*) TlsGetValue( store->tls );
     54 }
     55 
     56 void   thread_store_set( thread_store_t*          store,
     57                          void*                    value,
     58                          thread_store_destruct_t  destroy )
     59 {
     60     /* XXX: can't use destructor on thread exit */
     61     if (!store->lock_init) {
     62         store->lock_init = -1;
     63         InitializeCriticalSection( &store->lock );
     64         store->lock_init = -2;
     65     } else while (store->lock_init != -2) {
     66         Sleep(10); /* 10ms */
     67     }
     68 
     69     EnterCriticalSection( &store->lock );
     70     if (!store->has_tls) {
     71         store->tls = TlsAlloc();
     72         if (store->tls == TLS_OUT_OF_INDEXES) {
     73             LeaveCriticalSection( &store->lock );
     74             return;
     75         }
     76         store->has_tls = 1;
     77     }
     78     LeaveCriticalSection( &store->lock );
     79 
     80     TlsSetValue( store->tls, value );
     81 }
     82 #endif
     83