ManagedStatic.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements the ManagedStatic class and llvm_shutdown().
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Support/ManagedStatic.h"
  13. #include "llvm/Config/config.h"
  14. #include "llvm/Support/Threading.h"
  15. #include <cassert>
  16. #ifdef __APPLE__
  17. #include <TargetConditionals.h>
  18. #if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
  19. #include <llvm-c/Support.h>
  20. #include "ios_error.h"
  21. #undef write
  22. #undef exit
  23. #endif
  24. #endif
  25. #include <mutex>
  26. using namespace llvm;
  27. static const ManagedStaticBase *StaticList = nullptr;
  28. static std::recursive_mutex *ManagedStaticMutex = nullptr;
  29. static llvm::once_flag mutex_init_flag;
  30. static void initializeMutex() {
  31. ManagedStaticMutex = new std::recursive_mutex();
  32. }
  33. static std::recursive_mutex *getManagedStaticMutex() {
  34. llvm::call_once(mutex_init_flag, initializeMutex);
  35. return ManagedStaticMutex;
  36. }
  37. void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
  38. void (*Deleter)(void*)) const {
  39. assert(Creator);
  40. if (llvm_is_multithreaded()) {
  41. std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex());
  42. if (!Ptr.load(std::memory_order_relaxed)) {
  43. void *Tmp = Creator();
  44. Ptr.store(Tmp, std::memory_order_release);
  45. DeleterFn = Deleter;
  46. // Add to list of managed statics.
  47. Next = StaticList;
  48. StaticList = this;
  49. }
  50. } else {
  51. assert(!Ptr && !DeleterFn && !Next &&
  52. "Partially initialized ManagedStatic!?");
  53. Ptr = Creator();
  54. DeleterFn = Deleter;
  55. // Add to list of managed statics.
  56. Next = StaticList;
  57. StaticList = this;
  58. }
  59. }
  60. void ManagedStaticBase::destroy() const {
  61. assert(DeleterFn && "ManagedStatic not initialized correctly!");
  62. assert(StaticList == this &&
  63. "Not destroyed in reverse order of construction?");
  64. // Unlink from list.
  65. StaticList = Next;
  66. Next = nullptr;
  67. // Destroy memory.
  68. DeleterFn(Ptr);
  69. // Cleanup.
  70. Ptr = nullptr;
  71. DeleterFn = nullptr;
  72. }
  73. /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
  74. void llvm::llvm_shutdown() {
  75. std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex());
  76. while (StaticList)
  77. StaticList->destroy();
  78. #if TARGET_OS_IPHONE
  79. // Reset signal handler(s) (except SIGUSR2, reserved by Python):
  80. (void)signal(SIGUSR1, SIG_DFL);
  81. (void)signal(SIGHUP, SIG_DFL);
  82. (void)signal(SIGINT, SIG_DFL);
  83. (void)signal(SIGPIPE, SIG_DFL);
  84. (void)signal(SIGTERM, SIG_DFL);
  85. (void)signal(SIGILL, SIG_DFL);
  86. (void)signal(SIGTRAP, SIG_DFL);
  87. (void)signal(SIGABRT, SIG_DFL);
  88. (void)signal(SIGFPE, SIG_DFL);
  89. (void)signal(SIGBUS, SIG_DFL);
  90. (void)signal(SIGSEGV, SIG_DFL);
  91. (void)signal(SIGQUIT, SIG_DFL);
  92. (void)signal(SIGINFO, SIG_DFL);
  93. #endif
  94. }