atexit_thread.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Copyright (C) 2012-2022 Free Software Foundation, Inc.
  2. //
  3. // This file is part of GCC.
  4. //
  5. // GCC is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // GCC is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. #include <cxxabi.h>
  21. #include <cstdlib>
  22. #include <new>
  23. #include "bits/gthr.h"
  24. #ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
  25. #define WIN32_LEAN_AND_MEAN
  26. #include <windows.h>
  27. #endif
  28. // Simplify it a little for this file.
  29. #ifndef _GLIBCXX_CDTOR_CALLABI
  30. # define _GLIBCXX_CDTOR_CALLABI
  31. #endif
  32. #if _GLIBCXX_HAVE___CXA_THREAD_ATEXIT
  33. // Libc provides __cxa_thread_atexit definition.
  34. #elif _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL
  35. extern "C" int __cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
  36. void *arg, void *d);
  37. extern "C" int
  38. __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
  39. void *obj, void *dso_handle)
  40. _GLIBCXX_NOTHROW
  41. {
  42. return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
  43. }
  44. #else /* _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
  45. namespace {
  46. // One element in a singly-linked stack of cleanups.
  47. struct elt
  48. {
  49. void (_GLIBCXX_CDTOR_CALLABI *destructor)(void *);
  50. void *object;
  51. elt *next;
  52. #ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
  53. HMODULE dll;
  54. #endif
  55. };
  56. // Keep a per-thread list of cleanups in gthread_key storage.
  57. __gthread_key_t key;
  58. // But also support non-threaded mode.
  59. elt *single_thread;
  60. // Run the specified stack of cleanups.
  61. void run (void *p)
  62. {
  63. elt *e = static_cast<elt*>(p);
  64. while (e)
  65. {
  66. elt *old_e = e;
  67. e->destructor (e->object);
  68. #ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
  69. /* Decrement DLL count */
  70. if (e->dll)
  71. FreeLibrary (e->dll);
  72. #endif
  73. e = e->next;
  74. delete (old_e);
  75. }
  76. }
  77. // Run the stack of cleanups for the current thread.
  78. void run ()
  79. {
  80. void *e;
  81. if (__gthread_active_p ())
  82. {
  83. e = __gthread_getspecific (key);
  84. __gthread_setspecific (key, NULL);
  85. }
  86. else
  87. {
  88. e = single_thread;
  89. single_thread = NULL;
  90. }
  91. run (e);
  92. }
  93. // Initialize the key for the cleanup stack. We use a static local for
  94. // key init/delete rather than atexit so that delete is run on dlclose.
  95. void key_init() {
  96. struct key_s {
  97. key_s() { __gthread_key_create (&key, run); }
  98. ~key_s() { __gthread_key_delete (key); }
  99. };
  100. static key_s ks;
  101. // Also make sure the destructors are run by std::exit.
  102. // FIXME TLS cleanups should run before static cleanups and atexit
  103. // cleanups.
  104. std::atexit (run);
  105. }
  106. }
  107. extern "C" int
  108. __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
  109. void *obj, void */*dso_handle*/)
  110. _GLIBCXX_NOTHROW
  111. {
  112. // Do this initialization once.
  113. if (__gthread_active_p ())
  114. {
  115. // When threads are active use __gthread_once.
  116. static __gthread_once_t once = __GTHREAD_ONCE_INIT;
  117. __gthread_once (&once, key_init);
  118. }
  119. else
  120. {
  121. // And when threads aren't active use a static local guard.
  122. static bool queued;
  123. if (!queued)
  124. {
  125. queued = true;
  126. std::atexit (run);
  127. }
  128. }
  129. elt *first;
  130. if (__gthread_active_p ())
  131. first = static_cast<elt*>(__gthread_getspecific (key));
  132. else
  133. first = single_thread;
  134. elt *new_elt = new (std::nothrow) elt;
  135. if (!new_elt)
  136. return -1;
  137. new_elt->destructor = dtor;
  138. new_elt->object = obj;
  139. new_elt->next = first;
  140. #ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
  141. /* Store the DLL address for a later call to FreeLibrary in new_elt and
  142. increment DLL load count. This blocks the unloading of the DLL
  143. before the thread-local dtors have been called. This does NOT help
  144. if FreeLibrary/dlclose is called in excess. */
  145. GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
  146. (LPCWSTR) dtor, &new_elt->dll);
  147. #endif
  148. if (__gthread_active_p ())
  149. __gthread_setspecific (key, new_elt);
  150. else
  151. single_thread = new_elt;
  152. return 0;
  153. }
  154. #endif /* _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */