1 /*
2 * (c) 2004-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
4 *
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
8 *
9 * As a special exception, you may use this file as part of a free software
10 * library without restriction. Specifically, if other files instantiate
11 * templates or use macros or inline functions from this file, or you compile
12 * this file and link it with other files to produce an executable, this
13 * file does not by itself cause the resulting executable to be covered by
14 * the GNU General Public License. This exception does not however
15 * invalidate any other reasons why the executable file might be covered by
16 * the GNU General Public License.
17 */
18
19 #include "cxx_atexit.h"
20
21 #define NUM_ATEXIT 64
22
23 struct __exit_handler
24 {
25 void (*f)(void *);
26 void *arg;
27 void *dso_handle;
28 };
29
30 static __exit_handler __atexitlist[NUM_ATEXIT];
31 static volatile unsigned atexit_counter;
__cxa_atexit(void (* f)(void *),void * arg,void * dso_handle)32 int __cxa_atexit(void (*f)(void*), void *arg, void *dso_handle)
33 {
34 unsigned c = atexit_counter++;
35 if (c >= NUM_ATEXIT)
36 return -1;
37
38 __atexitlist[c].f = f;
39 __atexitlist[c].arg = arg;
40 __atexitlist[c].dso_handle = dso_handle;
41
42 return 0;
43 }
44
45 extern void *__dso_handle __attribute__((weak));
46
atexit(void (* f)(void))47 int atexit(void (*f)(void))
48 {
49 return __cxa_atexit((void (*)(void*))f, 0, (!&__dso_handle)?0:__dso_handle);
50 }
51
__cxa_finalize(void * dso_handle)52 void __cxa_finalize(void *dso_handle)
53 {
54 unsigned co = atexit_counter;
55 if (co > NUM_ATEXIT)
56 co = NUM_ATEXIT;
57
58 while(co)
59 {
60 __exit_handler *h = &__atexitlist[--co];
61 if (h->f && (dso_handle == 0 || h->dso_handle == dso_handle))
62 {
63 h->f(h->arg);
64 h->f = 0;
65 }
66 }
67 }
68