xref: /reactos/sdk/lib/crt/startup/atonexit.c (revision 8a6d6530)
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)30 void __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)97 atexit (_PVFV func)
98 {
99   return (_onexit((_onexit_t)func) == NULL) ? -1 : 0;
100 }
101