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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public