JsrtContext.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. #include "JsrtPch.h"
  6. #include "JsrtRuntime.h"
  7. #include "Base/ThreadContextTlsEntry.h"
  8. static THREAD_LOCAL JsrtContext* s_tlvSlot = nullptr;
  9. JsrtContext::JsrtContext(JsrtRuntime * runtime) :
  10. runtime(runtime), javascriptLibrary(nullptr)
  11. {
  12. }
  13. void JsrtContext::SetJavascriptLibrary(Js::JavascriptLibrary * library)
  14. {
  15. this->javascriptLibrary = library;
  16. if (this->javascriptLibrary)
  17. {
  18. this->javascriptLibrary->SetJsrtContext(this);
  19. }
  20. }
  21. void JsrtContext::Link()
  22. {
  23. // Link this new JsrtContext up in the JsrtRuntime's context list
  24. this->next = runtime->contextList;
  25. this->previous = nullptr;
  26. if (runtime->contextList != nullptr)
  27. {
  28. Assert(runtime->contextList->previous == nullptr);
  29. runtime->contextList->previous = this;
  30. }
  31. runtime->contextList = this;
  32. }
  33. void JsrtContext::Unlink()
  34. {
  35. // Unlink from JsrtRuntime JsrtContext list
  36. if (this->previous == nullptr)
  37. {
  38. // Have to check this because if we failed while creating, it might
  39. // never have gotten linked in to the runtime at all.
  40. if (this->runtime->contextList == this)
  41. {
  42. this->runtime->contextList = this->next;
  43. }
  44. }
  45. else
  46. {
  47. Assert(this->previous->next == this);
  48. this->previous->next = this->next;
  49. }
  50. if (this->next != nullptr)
  51. {
  52. Assert(this->next->previous == this);
  53. this->next->previous = this->previous;
  54. }
  55. }
  56. /* static */
  57. JsrtContext * JsrtContext::GetCurrent()
  58. {
  59. return s_tlvSlot;
  60. }
  61. /* static */
  62. bool JsrtContext::TrySetCurrent(JsrtContext * context)
  63. {
  64. ThreadContext * threadContext;
  65. //We are not pinning the context after SetCurrentContext, so if the context is not pinned
  66. //it might be reclaimed half way during execution. In jsrtshell the runtime was optimized out
  67. //at time of JsrtContext::Run by the compiler.
  68. //The change is to pin the context at setconcurrentcontext, and unpin the previous one. In
  69. //JsDisposeRuntime we'll reject if current context is active, so that will make sure all
  70. //contexts are unpinned at time of JsDisposeRuntime.
  71. if (context != nullptr)
  72. {
  73. threadContext = context->GetScriptContext()->GetThreadContext();
  74. if (!ThreadContextTLSEntry::TrySetThreadContext(threadContext))
  75. {
  76. return false;
  77. }
  78. // no need to rootAddRef and Release for the same context
  79. if (s_tlvSlot == context) return true;
  80. threadContext->GetRecycler()->RootAddRef((LPVOID)context);
  81. }
  82. else
  83. {
  84. if (!ThreadContextTLSEntry::ClearThreadContext(true))
  85. {
  86. return false;
  87. }
  88. }
  89. JsrtContext* originalContext = s_tlvSlot;
  90. if (originalContext != nullptr)
  91. {
  92. originalContext->GetScriptContext()->GetRecycler()->RootRelease((LPVOID) originalContext);
  93. }
  94. s_tlvSlot = context;
  95. return true;
  96. }
  97. void JsrtContext::Mark(Recycler * recycler)
  98. {
  99. AssertMsg(false, "Mark called on object that isn't TrackableObject");
  100. }