Update.
[glibc.git] / stdlib / cxa_atexit.c
bloba3d4c5037dc53ac0068fc7f839276fd8ddf59f32
1 /* Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
19 #include <bits/libc-lock.h>
20 #include <stdlib.h>
21 #include "exit.h"
23 #undef __cxa_atexit
25 /* Register a function to be called by exit or when a shared library
26 is unloaded. This function is only called from code generated by
27 the C++ compiler. */
28 int
29 __cxa_atexit (void (*func) (void *), void *arg, void *d)
31 struct exit_function *new = __new_exitfn ();
33 if (new == NULL)
34 return -1;
36 new->flavor = ef_cxa;
37 new->func.cxa.fn = (void (*) (void *, int)) func;
38 new->func.cxa.arg = arg;
39 new->func.cxa.dso_handle = d;
40 return 0;
42 INTDEF(__cxa_atexit)
45 /* We change global data, so we need locking. */
46 __libc_lock_define_initialized (static, lock)
49 static struct exit_function_list initial;
50 struct exit_function_list *__exit_funcs = &initial;
52 struct exit_function *
53 __new_exitfn (void)
55 struct exit_function_list *l;
56 size_t i = 0;
58 __libc_lock_lock (lock);
60 for (l = __exit_funcs; l != NULL; l = l->next)
62 for (i = 0; i < l->idx; ++i)
63 if (l->fns[i].flavor == ef_free)
64 break;
65 if (i < l->idx)
66 break;
68 if (l->idx < sizeof (l->fns) / sizeof (l->fns[0]))
70 i = l->idx++;
71 break;
75 if (l == NULL)
77 l = (struct exit_function_list *)
78 malloc (sizeof (struct exit_function_list));
79 if (l != NULL)
81 l->next = __exit_funcs;
82 __exit_funcs = l;
84 l->idx = 1;
85 i = 0;
89 /* Mark entry as used, but we don't know the flavor now. */
90 if (l != NULL)
91 l->fns[i].flavor = ef_us;
93 __libc_lock_unlock (lock);
95 return l == NULL ? NULL : &l->fns[i];