// Copyright (C) 2012-2024 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.

// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

#include <cxxabi.h>
#include <cstdlib>
#include <new>
#include "bits/gthr.h"

#ifdef __USING_MCFGTHREAD__

#include <mcfgthread/cxa.h>

namespace __cxxabiv1 {

extern "C" int
__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
		     void *obj, void *dso_handle) _GLIBCXX_NOTHROW
{
  return __MCF_cxa_thread_atexit (dtor, obj, dso_handle);
}

}  // namespace __cxxabiv1

#else // __USING_MCFGTHREAD__

#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

// Simplify it a little for this file.
#ifndef _GLIBCXX_CDTOR_CALLABI
#  define _GLIBCXX_CDTOR_CALLABI
#endif

#if _GLIBCXX_HAVE___CXA_THREAD_ATEXIT

// Libc provides __cxa_thread_atexit definition.

#elif _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL

extern "C" int __cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
					 void *arg, void *d);
extern "C" int
__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
				 void *obj, void *dso_handle)
  _GLIBCXX_NOTHROW
{
  return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
}

#else /* _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */

namespace {
  // One element in a singly-linked stack of cleanups.
  struct elt
  {
    void (_GLIBCXX_CDTOR_CALLABI *destructor)(void *);
    void *object;
    elt *next;
#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
    HMODULE dll;
#endif
  };

  // Keep a per-thread list of cleanups in gthread_key storage.
  __gthread_key_t key;
  // But also support non-threaded mode.
  elt *single_thread;

  // Run the specified stack of cleanups.
  void run (void *p)
  {
    elt *e = static_cast<elt*>(p);
    while (e)
      {
	elt *old_e = e;
	e->destructor (e->object);
#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
	/* Decrement DLL count */
	if (e->dll)
	  FreeLibrary (e->dll);
#endif
	e = e->next;
	delete (old_e);
      }
  }

  // Run the stack of cleanups for the current thread.
  void run ()
  {
    void *e;
    if (__gthread_active_p ())
      {
	e = __gthread_getspecific (key);
	__gthread_setspecific (key, NULL);
      }
    else
      {
	e = single_thread;
	single_thread = NULL;
      }
    run (e);
  }

  // Initialize the key for the cleanup stack.  We use a static local for
  // key init/delete rather than atexit so that delete is run on dlclose.
  void key_init() {
    struct key_s {
      key_s() { __gthread_key_create (&key, run); }
      ~key_s() { __gthread_key_delete (key); }
    };
    static key_s ks;
    // Also make sure the destructors are run by std::exit.
    // FIXME TLS cleanups should run before static cleanups and atexit
    // cleanups.
    std::atexit (run);
  }
}

#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
extern "C"
int __attribute__ ((__weak__))
__cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
			  void *arg, void *d);
#endif

// ??? We can't make it an ifunc, can we?
extern "C" int
__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
				 void *obj, [[maybe_unused]] void *dso_handle)
  _GLIBCXX_NOTHROW
{
#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
  if (__cxa_thread_atexit_impl)
    // Rely on a (presumably libc-provided) __cxa_thread_atexit_impl,
    // if it happens to be defined, even if configure couldn't find it
    // during the build.  _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
    // may be defined e.g. in os_defines.h on platforms where some
    // versions of libc have a __cxa_thread_atexit_impl definition,
    // but whose earlier versions didn't.  This enables programs build
    // by toolchains compatible with earlier libc versions to still
    // benefit from a libc-provided __cxa_thread_atexit_impl.
    return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
#endif

  // Do this initialization once.
  if (__gthread_active_p ())
    {
      // When threads are active use __gthread_once.
      static __gthread_once_t once = __GTHREAD_ONCE_INIT;
      __gthread_once (&once, key_init);
    }
  else
    {
      // And when threads aren't active use a static local guard.
      static bool queued;
      if (!queued)
	{
	  queued = true;
	  std::atexit (run);
	}
    }

  elt *first;
  if (__gthread_active_p ())
    first = static_cast<elt*>(__gthread_getspecific (key));
  else
    first = single_thread;

  elt *new_elt = new (std::nothrow) elt;
  if (!new_elt)
    return -1;
  new_elt->destructor = dtor;
  new_elt->object = obj;
  new_elt->next = first;
#ifdef _GLIBCXX_THREAD_ATEXIT_WIN32
  /* Store the DLL address for a later call to FreeLibrary in new_elt and
     increment DLL load count.  This blocks the unloading of the DLL
     before the thread-local dtors have been called.  This does NOT help
     if FreeLibrary/dlclose is called in excess. */
  GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
		      (LPCWSTR) dtor, &new_elt->dll);
#endif

  if (__gthread_active_p ())
    __gthread_setspecific (key, new_elt);
  else
    single_thread = new_elt;

  return 0;
}

#endif /* _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */

#endif // __USING_MCFGTHREAD__
