This will report runtime error if _CRT_INIT(DLL_PROCESS_DETACH) is called
by the current thread from some atexit_table hook.

Without this guard the _CRT_INIT(DLL_PROCESS_DETACH) function stay in the
infinite loop.

Startup code from Visual C++ runtime is doing same thing.
---
 mingw-w64-crt/crt/crtdll.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/mingw-w64-crt/crt/crtdll.c b/mingw-w64-crt/crt/crtdll.c
index bf2399d27e57..6829f5a1c136 100644
--- a/mingw-w64-crt/crt/crtdll.c
+++ b/mingw-w64-crt/crt/crtdll.c
@@ -118,8 +118,16 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD 
dwReason, LPVOID lpreserved)
   else if (dwReason == DLL_PROCESS_DETACH)
     {
       void *lock_free = NULL;
-      while ((lock_free = InterlockedCompareExchangePointer 
(&__native_startup_lock, (PVOID) 1, NULL)) != 0)
+      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)
@@ -130,6 +138,9 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD 
dwReason, LPVOID lpreserved)
        {
           _execute_onexit_table(&atexit_table);
          __native_startup_state = __uninitialized;
+       }
+      if (! nested)
+       {
          (void) InterlockedExchangePointer (&__native_startup_lock, NULL);
        }
     }
-- 
2.20.1



_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to