diff --git a/dll/win32/msvcrt/msvcrt.spec b/dll/win32/msvcrt/msvcrt.spec index 00bf4e65f3d..848e2602e45 100644 --- a/dll/win32/msvcrt/msvcrt.spec +++ b/dll/win32/msvcrt/msvcrt.spec @@ -883,7 +883,7 @@ @ stub -version=0x600+ -arch=i386 _msize_debug @ cdecl _nextafter(double double) @ stub -arch=x86_64 _nextafterf -@ cdecl _onexit(ptr) +@ extern _onexit # Declaring it as extern let us use the symbol from msvcrtex while having the __imp_ symbol defined in the import lib @ varargs _open(str long) @ cdecl _open_osfhandle(long long) @ extern _osplatform @@ -1293,7 +1293,7 @@ @ cdecl atan2(double double) @ cdecl -arch=x86_64,arm atan2f(long) @ cdecl -arch=x86_64,arm atanf(long) -@ extern atexit # <-- keep this as an extern, thank you +@ extern atexit # Declaring it as extern let us use the symbol from msvcrtex while having the __imp_ symbol defined in the import lib for those who really need it @ cdecl atof(str) @ cdecl atoi(str) @ cdecl atol(str) diff --git a/sdk/lib/crt/startup/atonexit.c b/sdk/lib/crt/startup/atonexit.c index 1774e90f1b3..ff6021aacfe 100644 --- a/sdk/lib/crt/startup/atonexit.c +++ b/sdk/lib/crt/startup/atonexit.c @@ -4,7 +4,6 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ -#undef CRTDLL #ifndef _DLL #define _DLL #endif @@ -20,7 +19,7 @@ void __cdecl _lock (int _File); void __cdecl _unlock (int _File); - + _PVFV *__onexitbegin; _PVFV *__onexitend; @@ -33,16 +32,19 @@ void __call_atexit(void) /* Note: should only be called with the exit lock held */ _PVFV *first, *last; - first = (_PVFV *)_decode_pointer(__onexitbegin); - last = (_PVFV *)_decode_pointer(__onexitend);; + if (!__onexitbegin) + return; - if (!first) return; + first = (_PVFV *)_decode_pointer(__onexitbegin); + last = (_PVFV *)_decode_pointer(__onexitend); while (--last >= first) if (*last) (**last)(); free(first); + + __onexitbegin = __onexitend = NULL; } /* Choose a different name to prevent name conflicts. The CRT one works fine. */ @@ -50,34 +52,45 @@ _onexit_t __cdecl _onexit(_onexit_t func); _onexit_t __cdecl _onexit(_onexit_t func) { - _PVFV *onexitbegin; - _PVFV *onexitend; - _onexit_t retval; + _PVFV *onexitbegin; + _PVFV *onexitend; + _onexit_t retval; - onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); - - if (onexitbegin == (_PVFV *) -1) -#ifdef __REACTOS__ - { - onexitbegin = (_PVFV *)calloc(32, sizeof(_onexit_t)); - if (onexitbegin == NULL) - return NULL; - __onexitbegin = _encode_pointer(onexitbegin); - __onexitend = _encode_pointer(onexitbegin + 32); - } -#else - return (* __MINGW_IMP_SYMBOL(_onexit)) (func); +#ifndef CRTDLL + if (__onexitbegin == (_PVFV *) -1) + return (* __MINGW_IMP_SYMBOL(_onexit)) (func); #endif - _lock (_EXIT_LOCK1); - onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); - onexitend = (_PVFV *) _decode_pointer (__onexitend); - - retval = __dllonexit (func, &onexitbegin, &onexitend); - __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin); - __onexitend = (_PVFV *) _encode_pointer (onexitend); - _unlock (_EXIT_LOCK1); - return retval; + _lock (_EXIT_LOCK1); + + if (!__onexitbegin) + { + /* First time we are called. Initialize our array */ + onexitbegin = calloc(1, sizeof(*onexitbegin)); + if (!onexitbegin) + { + _unlock(_EXIT_LOCK1); + return NULL; + } + onexitend = onexitbegin; + } + else + { + onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); + onexitend = (_PVFV *) _decode_pointer (__onexitend); + } + + retval = __dllonexit (func, &onexitbegin, &onexitend); + + if (retval != NULL) + { + /* Update our globals in case of success */ + __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin); + __onexitend = (_PVFV *) _encode_pointer (onexitend); + } + + _unlock (_EXIT_LOCK1); + return retval; } int __cdecl diff --git a/sdk/lib/crt/startup/crtdll.c b/sdk/lib/crt/startup/crtdll.c index afe23284f50..b9f5838b9fb 100644 --- a/sdk/lib/crt/startup/crtdll.c +++ b/sdk/lib/crt/startup/crtdll.c @@ -62,14 +62,8 @@ static int __cdecl pre_c_init (void) { - _PVFV *onexitbegin; + __onexitend = __onexitbegin = NULL; - onexitbegin = (_PVFV *) malloc (32 * sizeof (_PVFV)); - __onexitend = __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin); - - if (onexitbegin == NULL) - return 1; - *onexitbegin = (_PVFV) NULL; return 0; } @@ -136,14 +130,15 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) } else { - _PVFV * onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); - if (onexitbegin) + if (__onexitbegin) { + _PVFV *onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); _PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend); while (--onexitend >= onexitbegin) if (*onexitend != NULL) (**onexitend) (); - free (onexitbegin); + if (!lpreserved) + free(onexitbegin); __onexitbegin = __onexitend = (_PVFV *) NULL; } __native_startup_state = __uninitialized; diff --git a/sdk/lib/crt/startup/crtexe.c b/sdk/lib/crt/startup/crtexe.c index a09d4b5b441..4e6f1e4d1f6 100644 --- a/sdk/lib/crt/startup/crtexe.c +++ b/sdk/lib/crt/startup/crtexe.c @@ -127,7 +127,7 @@ pre_c_init (void) __set_app_type(_GUI_APP); else __set_app_type (_CONSOLE_APP); - __onexitbegin = __onexitend = (_PVFV *) _encode_pointer ((_PVFV *)(-1)); + __onexitbegin = __onexitend = (_PVFV *)(-1); * __MINGW_IMP_SYMBOL(_fmode) = _fmode; * __MINGW_IMP_SYMBOL(_commode) = _commode;