• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkTLS.h"
9 #include "SkThread.h"
10 
11 static bool gOnce = false;
12 static DWORD gTlsIndex;
13 SK_DECLARE_STATIC_MUTEX(gMutex);
14 
PlatformGetSpecific(bool forceCreateTheSlot)15 void* SkTLS::PlatformGetSpecific(bool forceCreateTheSlot) {
16     if (!forceCreateTheSlot && !gOnce) {
17         return NULL;
18     }
19 
20     if (!gOnce) {
21         SkAutoMutexAcquire tmp(gMutex);
22         if (!gOnce) {
23             gTlsIndex = TlsAlloc();
24             gOnce = true;
25         }
26     }
27     return TlsGetValue(gTlsIndex);
28 }
29 
PlatformSetSpecific(void * ptr)30 void SkTLS::PlatformSetSpecific(void* ptr) {
31     SkASSERT(gOnce);
32     (void)TlsSetValue(gTlsIndex, ptr);
33 }
34 
35 // Call TLS destructors on thread exit. Code based on Chromium's
36 // base/threading/thread_local_storage_win.cc
37 #ifdef _WIN64
38 
39 #pragma comment(linker, "/INCLUDE:_tls_used")
40 #pragma comment(linker, "/INCLUDE:skia_tls_callback")
41 
42 #else
43 
44 #pragma comment(linker, "/INCLUDE:__tls_used")
45 #pragma comment(linker, "/INCLUDE:_skia_tls_callback")
46 
47 #endif
48 
onTLSCallback(PVOID unused,DWORD reason,PVOID unused2)49 void NTAPI onTLSCallback(PVOID unused, DWORD reason, PVOID unused2) {
50     if ((DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason) && gOnce) {
51         void* ptr = TlsGetValue(gTlsIndex);
52         if (ptr != NULL) {
53             SkTLS::Destructor(ptr);
54             TlsSetValue(gTlsIndex, NULL);
55         }
56     }
57 }
58 
59 extern "C" {
60 
61 #ifdef _WIN64
62 
63 #pragma const_seg(".CRT$XLB")
64 extern const PIMAGE_TLS_CALLBACK skia_tls_callback;
65 const PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback;
66 #pragma const_seg()
67 
68 #else
69 
70 #pragma data_seg(".CRT$XLB")
71 PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback;
72 #pragma data_seg()
73 
74 #endif
75 }
76