SkTLS_win.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. #include "include/core/SkTypes.h"
  8. #if defined(SK_BUILD_FOR_WIN)
  9. #include "include/private/SkMutex.h"
  10. #include "src/core/SkLeanWindows.h"
  11. #include "src/core/SkTLS.h"
  12. static bool gOnce = false;
  13. static DWORD gTlsIndex;
  14. void* SkTLS::PlatformGetSpecific(bool forceCreateTheSlot) {
  15. static SkMutex& mutex = *(new SkMutex);
  16. if (!forceCreateTheSlot && !gOnce) {
  17. return nullptr;
  18. }
  19. if (!gOnce) {
  20. SkAutoMutexExclusive tmp(mutex);
  21. if (!gOnce) {
  22. gTlsIndex = TlsAlloc();
  23. gOnce = true;
  24. }
  25. }
  26. return TlsGetValue(gTlsIndex);
  27. }
  28. void SkTLS::PlatformSetSpecific(void* ptr) {
  29. SkASSERT(gOnce);
  30. (void)TlsSetValue(gTlsIndex, ptr);
  31. }
  32. // Call TLS destructors on thread exit. Code based on Chromium's
  33. // base/threading/thread_local_storage_win.cc
  34. #ifdef _WIN64
  35. #pragma comment(linker, "/INCLUDE:_tls_used")
  36. #pragma comment(linker, "/INCLUDE:skia_tls_callback")
  37. #else
  38. #pragma comment(linker, "/INCLUDE:__tls_used")
  39. #pragma comment(linker, "/INCLUDE:_skia_tls_callback")
  40. #endif
  41. void NTAPI onTLSCallback(PVOID unused, DWORD reason, PVOID unused2) {
  42. if ((DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason) && gOnce) {
  43. void* ptr = TlsGetValue(gTlsIndex);
  44. if (ptr != nullptr) {
  45. SkTLS::Destructor(ptr);
  46. TlsSetValue(gTlsIndex, nullptr);
  47. }
  48. }
  49. }
  50. extern "C" {
  51. #ifdef _WIN64
  52. #pragma const_seg(".CRT$XLB")
  53. extern const PIMAGE_TLS_CALLBACK skia_tls_callback;
  54. const PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback;
  55. #pragma const_seg()
  56. #else
  57. #pragma data_seg(".CRT$XLB")
  58. PIMAGE_TLS_CALLBACK skia_tls_callback = onTLSCallback;
  59. #pragma data_seg()
  60. #endif
  61. }
  62. #endif//defined(SK_BUILD_FOR_WIN)