blob: cf7269b308eab740bc8c87afc323494fac9172eb [file] [log] [blame]
bungeman@google.comf2e7dbb2013-07-16 14:59:24 +00001/*
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 */
mtklein1ee76512015-11-02 10:20:27 -08007#include "SkTypes.h"
Mike Klein8f11d4d2018-01-24 12:42:55 -05008#if defined(SK_BUILD_FOR_WIN)
bungeman@google.comf2e7dbb2013-07-16 14:59:24 +00009
halcanary4dbbd042016-06-07 17:21:10 -070010#include "SkLeanWindows.h"
mtklein1b249332015-07-07 12:21:21 -070011#include "SkMutex.h"
halcanary4dbbd042016-06-07 17:21:10 -070012#include "SkTLS.h"
bungeman@google.comf2e7dbb2013-07-16 14:59:24 +000013
14static bool gOnce = false;
15static DWORD gTlsIndex;
reed086eea92016-05-04 17:12:46 -070016SK_DECLARE_STATIC_MUTEX(gMutex);
bungeman@google.comf2e7dbb2013-07-16 14:59:24 +000017
18void* SkTLS::PlatformGetSpecific(bool forceCreateTheSlot) {
19 if (!forceCreateTheSlot && !gOnce) {
halcanary96fcdcc2015-08-27 07:41:13 -070020 return nullptr;
bungeman@google.comf2e7dbb2013-07-16 14:59:24 +000021 }
22
23 if (!gOnce) {
24 SkAutoMutexAcquire tmp(gMutex);
25 if (!gOnce) {
26 gTlsIndex = TlsAlloc();
27 gOnce = true;
28 }
29 }
30 return TlsGetValue(gTlsIndex);
31}
32
33void SkTLS::PlatformSetSpecific(void* ptr) {
34 SkASSERT(gOnce);
35 (void)TlsSetValue(gTlsIndex, ptr);
36}
37
38// Call TLS destructors on thread exit. Code based on Chromium's
39// base/threading/thread_local_storage_win.cc
40#ifdef _WIN64
41
42#pragma comment(linker, "/INCLUDE:_tls_used")
43#pragma comment(linker, "/INCLUDE:skia_tls_callback")
44
45#else
46
47#pragma comment(linker, "/INCLUDE:__tls_used")
48#pragma comment(linker, "/INCLUDE:_skia_tls_callback")
49
50#endif
51
52void NTAPI onTLSCallback(PVOID unused, DWORD reason, PVOID unused2) {
53 if ((DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason) && gOnce) {
54 void* ptr = TlsGetValue(gTlsIndex);
halcanary96fcdcc2015-08-27 07:41:13 -070055 if (ptr != nullptr) {
bungeman@google.comf2e7dbb2013-07-16 14:59:24 +000056 SkTLS::Destructor(ptr);
halcanary96fcdcc2015-08-27 07:41:13 -070057 TlsSetValue(gTlsIndex, nullptr);
bungeman@google.comf2e7dbb2013-07-16 14:59:24 +000058 }
59 }
60}
61
62extern "C" {
63
64#ifdef _WIN64
65
66#pragma const_seg(".CRT$XLB")
67extern const PIMAGE_TLS_CALLBACK skia_tls_callback;
68const PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback;
69#pragma const_seg()
70
71#else
72
73#pragma data_seg(".CRT$XLB")
74PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback;
75#pragma data_seg()
76
77#endif
78}
mtklein1ee76512015-11-02 10:20:27 -080079
Mike Klein8f11d4d2018-01-24 12:42:55 -050080#endif//defined(SK_BUILD_FOR_WIN)