1 /** 2 * This file has no copyright assigned and is placed in the Public Domain. 3 * This file is part of the w64 mingw-runtime package. 4 * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5 */ 6 7 #ifndef _DLL 8 #define _DLL 9 #endif 10 11 #include <oscalls.h> 12 #include <internal.h> 13 #include <stdlib.h> 14 #include <crtdefs.h> 15 #include <limits.h> 16 //#include <windows.h> 17 18 #define _EXIT_LOCK1 8 19 20 void __cdecl _lock (int _File); 21 void __cdecl _unlock (int _File); 22 23 _PVFV *__onexitbegin; 24 _PVFV *__onexitend; 25 26 extern _onexit_t __cdecl __dllonexit (_onexit_t, _PVFV**, _PVFV**); 27 extern _onexit_t (__cdecl * __MINGW_IMP_SYMBOL(_onexit)) (_onexit_t func); 28 29 /* INTERNAL: call atexit functions */ __call_atexit(void)30void __call_atexit(void) 31 { 32 /* Note: should only be called with the exit lock held */ 33 _PVFV *first, *last; 34 35 if (!__onexitbegin) 36 return; 37 38 first = (_PVFV *)_decode_pointer(__onexitbegin); 39 last = (_PVFV *)_decode_pointer(__onexitend); 40 41 while (--last >= first) 42 if (*last) 43 (**last)(); 44 45 free(first); 46 47 __onexitbegin = __onexitend = NULL; 48 } 49 50 /* Choose a different name to prevent name conflicts. The CRT one works fine. */ 51 _onexit_t __cdecl _onexit(_onexit_t func); 52 _onexit(_onexit_t func)53_onexit_t __cdecl _onexit(_onexit_t func) 54 { 55 _PVFV *onexitbegin; 56 _PVFV *onexitend; 57 _onexit_t retval; 58 59 #ifndef CRTDLL 60 if (__onexitbegin == (_PVFV *) -1) 61 return (* __MINGW_IMP_SYMBOL(_onexit)) (func); 62 #endif 63 64 _lock (_EXIT_LOCK1); 65 66 if (!__onexitbegin) 67 { 68 /* First time we are called. Initialize our array */ 69 onexitbegin = calloc(1, sizeof(*onexitbegin)); 70 if (!onexitbegin) 71 { 72 _unlock(_EXIT_LOCK1); 73 return NULL; 74 } 75 onexitend = onexitbegin; 76 } 77 else 78 { 79 onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); 80 onexitend = (_PVFV *) _decode_pointer (__onexitend); 81 } 82 83 retval = __dllonexit (func, &onexitbegin, &onexitend); 84 85 if (retval != NULL) 86 { 87 /* Update our globals in case of success */ 88 __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin); 89 __onexitend = (_PVFV *) _encode_pointer (onexitend); 90 } 91 92 _unlock (_EXIT_LOCK1); 93 return retval; 94 } 95 96 int __cdecl atexit(_PVFV func)97atexit (_PVFV func) 98 { 99 return (_onexit((_onexit_t)func) == NULL) ? -1 : 0; 100 } 101