1f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com/*
2f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com * Copyright 2013 Google Inc.
3f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com *
4f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com * Use of this source code is governed by a BSD-style license that can be
5f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com * found in the LICENSE file.
6f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com */
71ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#include "SkTypes.h"
81ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#if defined(SK_BUILD_FOR_WIN32)
9f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
104dbbd04314cc0606f8d3bafe515c97e52c180f73halcanary#include "SkLeanWindows.h"
111b24933e52f50773de29332387a12721811f3012mtklein#include "SkMutex.h"
124dbbd04314cc0606f8d3bafe515c97e52c180f73halcanary#include "SkTLS.h"
13f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
14f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comstatic bool gOnce = false;
15f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comstatic DWORD gTlsIndex;
16086eea93b1f8253420c233c33cdabc0e74b08091reedSK_DECLARE_STATIC_MUTEX(gMutex);
17f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
18f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comvoid* SkTLS::PlatformGetSpecific(bool forceCreateTheSlot) {
19f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    if (!forceCreateTheSlot && !gOnce) {
2096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
21f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    }
22f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
23f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    if (!gOnce) {
24f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com        SkAutoMutexAcquire tmp(gMutex);
25f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com        if (!gOnce) {
26f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com            gTlsIndex = TlsAlloc();
27f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com            gOnce = true;
28f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com        }
29f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    }
30f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    return TlsGetValue(gTlsIndex);
31f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com}
32f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
33f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comvoid SkTLS::PlatformSetSpecific(void* ptr) {
34f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    SkASSERT(gOnce);
35f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    (void)TlsSetValue(gTlsIndex, ptr);
36f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com}
37f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
38f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com// Call TLS destructors on thread exit. Code based on Chromium's
39f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com// base/threading/thread_local_storage_win.cc
40f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#ifdef _WIN64
41f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
42f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#pragma comment(linker, "/INCLUDE:_tls_used")
43f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#pragma comment(linker, "/INCLUDE:skia_tls_callback")
44f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
45f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#else
46f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
47f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#pragma comment(linker, "/INCLUDE:__tls_used")
48f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#pragma comment(linker, "/INCLUDE:_skia_tls_callback")
49f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
50f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#endif
51f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
52f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comvoid NTAPI onTLSCallback(PVOID unused, DWORD reason, PVOID unused2) {
53f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    if ((DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason) && gOnce) {
54f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com        void* ptr = TlsGetValue(gTlsIndex);
5596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (ptr != nullptr) {
56f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com            SkTLS::Destructor(ptr);
5796fcdcc219d2a0d3579719b84b28bede76efba64halcanary            TlsSetValue(gTlsIndex, nullptr);
58f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com        }
59f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com    }
60f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com}
61f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
62f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comextern "C" {
63f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
64f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#ifdef _WIN64
65f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
66f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#pragma const_seg(".CRT$XLB")
67f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comextern const PIMAGE_TLS_CALLBACK skia_tls_callback;
68f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comconst PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback;
69f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#pragma const_seg()
70f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
71f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#else
72f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
73f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#pragma data_seg(".CRT$XLB")
74f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.comPIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback;
75f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#pragma data_seg()
76f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com
77f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com#endif
78f2e7dbb09fabc31fe5b16f6dc1a16593f518ca7dbungeman@google.com}
791ee76510f5dbf632d30975fc3509ef4f609156d2mtklein
801ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#endif//defined(SK_BUILD_FOR_WIN32)
81