1c2c66affSColin Finck /** 2c2c66affSColin Finck * This file has no copyright assigned and is placed in the Public Domain. 3c2c66affSColin Finck * This file is part of the w64 mingw-runtime package. 4c2c66affSColin Finck * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5c2c66affSColin Finck */ 6c2c66affSColin Finck 7c2c66affSColin Finck #ifndef _DLL 8c2c66affSColin Finck #define _DLL 9c2c66affSColin Finck #endif 10c2c66affSColin Finck 11c2c66affSColin Finck #include <oscalls.h> 12c2c66affSColin Finck #include <internal.h> 13c2c66affSColin Finck #include <stdlib.h> 14c2c66affSColin Finck #include <crtdefs.h> 15c2c66affSColin Finck #include <limits.h> 16c2c66affSColin Finck //#include <windows.h> 17c2c66affSColin Finck 18c2c66affSColin Finck #define _EXIT_LOCK1 8 19c2c66affSColin Finck 20c2c66affSColin Finck void __cdecl _lock (int _File); 21c2c66affSColin Finck void __cdecl _unlock (int _File); 22c2c66affSColin Finck 23c2c66affSColin Finck _PVFV *__onexitbegin; 24c2c66affSColin Finck _PVFV *__onexitend; 25c2c66affSColin Finck 262c791cddSTimo Kreuzer extern _onexit_t __cdecl __dllonexit (_onexit_t, _PVFV**, _PVFV**); 27c2c66affSColin Finck extern _onexit_t (__cdecl * __MINGW_IMP_SYMBOL(_onexit)) (_onexit_t func); 28c2c66affSColin Finck 292c791cddSTimo Kreuzer /* INTERNAL: call atexit functions */ __call_atexit(void)302c791cddSTimo Kreuzervoid __call_atexit(void) 312c791cddSTimo Kreuzer { 322c791cddSTimo Kreuzer /* Note: should only be called with the exit lock held */ 332c791cddSTimo Kreuzer _PVFV *first, *last; 34c2c66affSColin Finck 35*8a6d6530SJérôme Gardou if (!__onexitbegin) 36*8a6d6530SJérôme Gardou return; 372c791cddSTimo Kreuzer 38*8a6d6530SJérôme Gardou first = (_PVFV *)_decode_pointer(__onexitbegin); 39*8a6d6530SJérôme Gardou last = (_PVFV *)_decode_pointer(__onexitend); 402c791cddSTimo Kreuzer 412c791cddSTimo Kreuzer while (--last >= first) 422c791cddSTimo Kreuzer if (*last) 432c791cddSTimo Kreuzer (**last)(); 442c791cddSTimo Kreuzer 452c791cddSTimo Kreuzer free(first); 46*8a6d6530SJérôme Gardou 47*8a6d6530SJérôme Gardou __onexitbegin = __onexitend = NULL; 482c791cddSTimo Kreuzer } 492c791cddSTimo Kreuzer 502c791cddSTimo Kreuzer /* Choose a different name to prevent name conflicts. The CRT one works fine. */ 512c791cddSTimo Kreuzer _onexit_t __cdecl _onexit(_onexit_t func); 522c791cddSTimo Kreuzer _onexit(_onexit_t func)532c791cddSTimo Kreuzer_onexit_t __cdecl _onexit(_onexit_t func) 54c2c66affSColin Finck { 55c2c66affSColin Finck _PVFV *onexitbegin; 56c2c66affSColin Finck _PVFV *onexitend; 57c2c66affSColin Finck _onexit_t retval; 58c2c66affSColin Finck 59*8a6d6530SJérôme Gardou #ifndef CRTDLL 60*8a6d6530SJérôme Gardou if (__onexitbegin == (_PVFV *) -1) 61c2c66affSColin Finck return (* __MINGW_IMP_SYMBOL(_onexit)) (func); 622c791cddSTimo Kreuzer #endif 63*8a6d6530SJérôme Gardou 64c2c66affSColin Finck _lock (_EXIT_LOCK1); 65*8a6d6530SJérôme Gardou 66*8a6d6530SJérôme Gardou if (!__onexitbegin) 67*8a6d6530SJérôme Gardou { 68*8a6d6530SJérôme Gardou /* First time we are called. Initialize our array */ 69*8a6d6530SJérôme Gardou onexitbegin = calloc(1, sizeof(*onexitbegin)); 70*8a6d6530SJérôme Gardou if (!onexitbegin) 71*8a6d6530SJérôme Gardou { 72*8a6d6530SJérôme Gardou _unlock(_EXIT_LOCK1); 73*8a6d6530SJérôme Gardou return NULL; 74*8a6d6530SJérôme Gardou } 75*8a6d6530SJérôme Gardou onexitend = onexitbegin; 76*8a6d6530SJérôme Gardou } 77*8a6d6530SJérôme Gardou else 78*8a6d6530SJérôme Gardou { 79c2c66affSColin Finck onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); 80c2c66affSColin Finck onexitend = (_PVFV *) _decode_pointer (__onexitend); 81*8a6d6530SJérôme Gardou } 82c2c66affSColin Finck 83c2c66affSColin Finck retval = __dllonexit (func, &onexitbegin, &onexitend); 84c2c66affSColin Finck 85*8a6d6530SJérôme Gardou if (retval != NULL) 86*8a6d6530SJérôme Gardou { 87*8a6d6530SJérôme Gardou /* Update our globals in case of success */ 88c2c66affSColin Finck __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin); 89c2c66affSColin Finck __onexitend = (_PVFV *) _encode_pointer (onexitend); 90*8a6d6530SJérôme Gardou } 91*8a6d6530SJérôme Gardou 92c2c66affSColin Finck _unlock (_EXIT_LOCK1); 93c2c66affSColin Finck return retval; 94c2c66affSColin Finck } 95c2c66affSColin Finck 96c2c66affSColin Finck int __cdecl atexit(_PVFV func)97c2c66affSColin Finckatexit (_PVFV func) 98c2c66affSColin Finck { 992c791cddSTimo Kreuzer return (_onexit((_onexit_t)func) == NULL) ? -1 : 0; 100c2c66affSColin Finck } 101