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