/**
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is part of the mingw-w64 runtime package.
 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 */

#include <oscalls.h>
#include <internal.h>
#include <stdlib.h>
#include <windows.h>
#define _DECL_DLLMAIN
#include <process.h>
#include <crtdbg.h>

#ifndef _CRTIMP
#define _CRTIMP __declspec(dllimport)
#endif
#include <sect_attribs.h>
#include <locale.h>

#if defined(__x86_64__) && !defined(__SEH__)
extern int __mingw_init_ehandler (void);
#endif
extern void __main ();
extern void _pei386_runtime_relocator (void);
extern _PIFV __xi_a[];
extern _PIFV __xi_z[];
extern _PVFV __xc_a[];
extern _PVFV __xc_z[];


/* TLS initialization hook.  */
extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;

static int __proc_attached = 0;

static _onexit_table_t atexit_table;

extern int __mingw_app_type;

WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
{
  if (dwReason == DLL_PROCESS_DETACH)
    {
      if (__proc_attached > 0)
	__proc_attached--;
      else
	return FALSE;
    }
  if (dwReason == DLL_PROCESS_ATTACH)
    {
      void *lock_free = NULL;
      void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase;
      BOOL nested = FALSE;
      int ret = 0;
      
      while ((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock,
							     fiberid, NULL)) != 0)
	{
	  if (lock_free == fiberid)
	    {
	      nested = TRUE;
	      break;
	    }
	  Sleep(1000);
	}
      if (__native_startup_state != __uninitialized)
	{
	  _amsg_exit (31);
	}
      else
	{
	  __native_startup_state = __initializing;
	  
	  _pei386_runtime_relocator ();
#if defined(__x86_64__) && !defined(__SEH__)
	  __mingw_init_ehandler ();
#endif
	  ret = _initialize_onexit_table (&atexit_table);
	  if (ret != 0)
	    goto i__leave;
	  ret = _initterm_e (__xi_a, __xi_z);
	  if (ret != 0)
	    goto i__leave;
	  _initterm (__xc_a, __xc_z);
	  __main ();

	  __native_startup_state = __initialized;
	}
i__leave:
      if (! nested)
	{
	  (void) InterlockedExchangePointer (&__native_startup_lock, NULL);
	}
      if (ret != 0)
	{
	  return FALSE;
	}
      if (__dyn_tls_init_callback != NULL)
	{
	  __dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved);
	}
      __proc_attached++;
    }
  else if (dwReason == DLL_PROCESS_DETACH)
    {
      void *lock_free = NULL;
      void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase;
      BOOL nested = FALSE;

      while ((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock, fiberid, NULL)) != 0)
	{
	  if (lock_free == fiberid)
	    {
	      nested = TRUE;
	      break;
	    }
	  Sleep(1000);
	}
      if (__native_startup_state != __initialized)
	{
	  _amsg_exit (31);
	}
      else
	{
          _execute_onexit_table(&atexit_table);
	  __native_startup_state = __uninitialized;
	}
      if (! nested)
	{
	  (void) InterlockedExchangePointer (&__native_startup_lock, NULL);
	}
    }
  return TRUE;
}

WINBOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID);

#if defined(__i386__) || defined(_X86_)
/* We need to make sure that we align the stack to 16 bytes for the sake of SSE
   opts in DllMain or in functions called from DllMain.  */
__attribute__((force_align_arg_pointer))
#endif
__attribute__((used)) /* required due to GNU LD bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30300 */
WINBOOL WINAPI
DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
{
  WINBOOL retcode = TRUE;

  if (dwReason == DLL_PROCESS_ATTACH)
    __mingw_app_type = 0;

  __native_dllmain_reason = dwReason;
  if (dwReason == DLL_PROCESS_DETACH && __proc_attached <= 0)
    {
	retcode = FALSE;
	goto i__leave;
    }

  if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH)
    {
        retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved);
        if (!retcode)
          goto i__leave;
    }
  retcode = DllMain(hDllHandle,dwReason,lpreserved);
  if (dwReason == DLL_PROCESS_ATTACH && ! retcode)
    {
	DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
	_CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
    }
  if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
    {
	retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved);
    }
i__leave:
  __native_dllmain_reason = UINT_MAX;
  return retcode ;
}

int __cdecl atexit (_PVFV func)
{
    /* Do not use msvcrt's atexit() or UCRT's _crt_atexit() function as it
     * cannot be called from DLL library which may be unloaded at runtime. */
    return _register_onexit_function(&atexit_table, (_onexit_t)func);
}

char __mingw_module_is_dll = 1;
