ThreadContextTlsEntry.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. class ThreadContextTLSEntry
  7. {
  8. public:
  9. static bool InitializeProcess();
  10. static void CleanupProcess();
  11. static bool IsProcessInitialized();
  12. static void InitializeThread();
  13. static void CleanupThread();
  14. static void Delete(ThreadContextTLSEntry * entry);
  15. static bool TrySetThreadContext(ThreadContext * threadContext);
  16. static void SetThreadContext(ThreadContextTLSEntry * entry, ThreadContext * threadContext);
  17. static bool ClearThreadContext(bool isValid);
  18. static bool ClearThreadContext(ThreadContextTLSEntry * entry, bool isThreadContextValid, bool force = true);
  19. static ThreadContextTLSEntry * GetEntryForCurrentThread();
  20. static ThreadContextTLSEntry * CreateEntryForCurrentThread();
  21. static ThreadContextId GetThreadContextId(ThreadContext * threadContext);
  22. #ifdef _WIN32
  23. static uint32 s_tlsSlot;
  24. #endif
  25. ThreadContext * GetThreadContext();
  26. private:
  27. friend JsUtil::ExternalApi;
  28. static ThreadContextId GetCurrentThreadContextId();
  29. private:
  30. ThreadContext * threadContext;
  31. StackProber prober;
  32. };
  33. class ThreadContextScope
  34. {
  35. public:
  36. ThreadContextScope(ThreadContext * threadContext)
  37. {
  38. if (!threadContext->IsThreadBound())
  39. {
  40. originalContext = ThreadContextTLSEntry::GetEntryForCurrentThread() ?
  41. ThreadContextTLSEntry::GetEntryForCurrentThread()->GetThreadContext() : NULL;
  42. wasInUse = threadContext == originalContext;
  43. isValid = ThreadContextTLSEntry::TrySetThreadContext(threadContext);
  44. doCleanup = !wasInUse && isValid;
  45. }
  46. else
  47. {
  48. Assert(ThreadContext::GetContextForCurrentThread() == threadContext);
  49. isValid = true;
  50. wasInUse = true;
  51. doCleanup = false;
  52. }
  53. }
  54. ~ThreadContextScope()
  55. {
  56. if (doCleanup)
  57. {
  58. bool cleared = true;
  59. #if DBG
  60. cleared =
  61. #endif
  62. ThreadContextTLSEntry::ClearThreadContext(this->isValid);
  63. Assert(cleared);
  64. if (originalContext)
  65. {
  66. bool canSetback = true;
  67. #if DBG
  68. canSetback =
  69. #endif
  70. ThreadContextTLSEntry::TrySetThreadContext(originalContext);
  71. Assert(canSetback);
  72. }
  73. }
  74. }
  75. void Invalidate()
  76. {
  77. this->isValid = false;
  78. }
  79. bool IsValid() const
  80. {
  81. return this->isValid;
  82. }
  83. bool WasInUse() const
  84. {
  85. return this->wasInUse;
  86. }
  87. private:
  88. bool doCleanup;
  89. bool isValid;
  90. bool wasInUse;
  91. ThreadContext* originalContext;
  92. };