tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

tls.cpp (3747B)


      1 //
      2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // tls.cpp: Simple cross-platform interface for thread local storage.
      8 
      9 #include "common/tls.h"
     10 
     11 #include "common/debug.h"
     12 
     13 #ifdef ANGLE_ENABLE_WINDOWS_UWP
     14 #    include <map>
     15 #    include <mutex>
     16 #    include <set>
     17 #    include <vector>
     18 
     19 #    include <Windows.System.Threading.h>
     20 #    include <wrl/async.h>
     21 #    include <wrl/client.h>
     22 
     23 using namespace std;
     24 using namespace Windows::Foundation;
     25 using namespace ABI::Windows::System::Threading;
     26 
     27 // Thread local storage for Windows Store support
     28 typedef vector<void *> ThreadLocalData;
     29 
     30 static __declspec(thread) ThreadLocalData *currentThreadData = nullptr;
     31 static set<ThreadLocalData *> allThreadData;
     32 static DWORD nextTlsIndex = 0;
     33 static vector<DWORD> freeTlsIndices;
     34 
     35 #endif
     36 
     37 TLSIndex CreateTLSIndex(PthreadKeyDestructor destructor)
     38 {
     39    TLSIndex index;
     40 
     41 #ifdef ANGLE_PLATFORM_WINDOWS
     42 #    ifdef ANGLE_ENABLE_WINDOWS_UWP
     43    if (!freeTlsIndices.empty())
     44    {
     45        DWORD result = freeTlsIndices.back();
     46        freeTlsIndices.pop_back();
     47        index = result;
     48    }
     49    else
     50    {
     51        index = nextTlsIndex++;
     52    }
     53 #    else
     54    index = TlsAlloc();
     55 #    endif
     56 
     57 #elif defined(ANGLE_PLATFORM_POSIX)
     58    // Create pthread key
     59    if ((pthread_key_create(&index, destructor)) != 0)
     60    {
     61        index = TLS_INVALID_INDEX;
     62    }
     63 #endif
     64 
     65    ASSERT(index != TLS_INVALID_INDEX && "CreateTLSIndex: Unable to allocate Thread Local Storage");
     66    return index;
     67 }
     68 
     69 bool DestroyTLSIndex(TLSIndex index)
     70 {
     71    ASSERT(index != TLS_INVALID_INDEX && "DestroyTLSIndex(): Invalid TLS Index");
     72    if (index == TLS_INVALID_INDEX)
     73    {
     74        return false;
     75    }
     76 
     77 #ifdef ANGLE_PLATFORM_WINDOWS
     78 #    ifdef ANGLE_ENABLE_WINDOWS_UWP
     79    ASSERT(index < nextTlsIndex);
     80    ASSERT(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
     81 
     82    freeTlsIndices.push_back(index);
     83    for (auto threadData : allThreadData)
     84    {
     85        if (threadData->size() > index)
     86        {
     87            threadData->at(index) = nullptr;
     88        }
     89    }
     90    return true;
     91 #    else
     92    return (TlsFree(index) == TRUE);
     93 #    endif
     94 #elif defined(ANGLE_PLATFORM_POSIX)
     95    return (pthread_key_delete(index) == 0);
     96 #endif
     97 }
     98 
     99 bool SetTLSValue(TLSIndex index, void *value)
    100 {
    101    ASSERT(index != TLS_INVALID_INDEX && "SetTLSValue(): Invalid TLS Index");
    102    if (index == TLS_INVALID_INDEX)
    103    {
    104        return false;
    105    }
    106 
    107 #ifdef ANGLE_PLATFORM_WINDOWS
    108 #    ifdef ANGLE_ENABLE_WINDOWS_UWP
    109    ThreadLocalData *threadData = currentThreadData;
    110    if (!threadData)
    111    {
    112        threadData = new ThreadLocalData(index + 1, nullptr);
    113        allThreadData.insert(threadData);
    114        currentThreadData = threadData;
    115    }
    116    else if (threadData->size() <= index)
    117    {
    118        threadData->resize(index + 1, nullptr);
    119    }
    120 
    121    threadData->at(index) = value;
    122    return true;
    123 #    else
    124    return (TlsSetValue(index, value) == TRUE);
    125 #    endif
    126 #elif defined(ANGLE_PLATFORM_POSIX)
    127    return (pthread_setspecific(index, value) == 0);
    128 #endif
    129 }
    130 
    131 void *GetTLSValue(TLSIndex index)
    132 {
    133    ASSERT(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
    134    if (index == TLS_INVALID_INDEX)
    135    {
    136        return nullptr;
    137    }
    138 
    139 #ifdef ANGLE_PLATFORM_WINDOWS
    140 #    ifdef ANGLE_ENABLE_WINDOWS_UWP
    141    ThreadLocalData *threadData = currentThreadData;
    142    if (threadData && threadData->size() > index)
    143    {
    144        return threadData->at(index);
    145    }
    146    else
    147    {
    148        return nullptr;
    149    }
    150 #    else
    151    return TlsGetValue(index);
    152 #    endif
    153 #elif defined(ANGLE_PLATFORM_POSIX)
    154    return pthread_getspecific(index);
    155 #endif
    156 }