Update.
[glibc.git] / stdlib / cxa_atexit.c
blobf602b7a1afa7a7bfe828f1fbababd833eea27654
1 /* Copyright (C) 1999, 2001 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 Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 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 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
19 #include <bits/libc-lock.h>
20 #include <stdlib.h>
21 #include "exit.h"
23 /* Register a function to be called by exit or when a shared library
24 is unloaded. This function is only called from code generated by
25 the C++ compiler. */
26 int
27 __cxa_atexit (void (*func) (void *), void *arg, void *d)
29 struct exit_function *new = __new_exitfn ();
31 if (new == NULL)
32 return -1;
34 new->flavor = ef_cxa;
35 new->func.cxa.fn = (void (*) (void *, int)) func;
36 new->func.cxa.arg = arg;
37 new->func.cxa.dso_handle = d;
38 return 0;
42 /* We change global data, so we need locking. */
43 __libc_lock_define_initialized (static, lock)
46 static struct exit_function_list initial;
47 struct exit_function_list *__exit_funcs = &initial;
49 struct exit_function *
50 __new_exitfn (void)
52 struct exit_function_list *l;
53 size_t i = 0;
55 __libc_lock_lock (lock);
57 for (l = __exit_funcs; l != NULL; l = l->next)
59 for (i = 0; i < l->idx; ++i)
60 if (l->fns[i].flavor == ef_free)
61 break;
62 if (i < l->idx)
63 break;
65 if (l->idx < sizeof (l->fns) / sizeof (l->fns[0]))
67 i = l->idx++;
68 break;
72 if (l == NULL)
74 l = (struct exit_function_list *)
75 malloc (sizeof (struct exit_function_list));
76 if (l != NULL)
78 l->next = __exit_funcs;
79 __exit_funcs = l;
81 l->idx = 1;
82 i = 0;
86 /* Mark entry as used, but we don't know the flavor now. */
87 if (l != NULL)
88 l->fns[i].flavor = ef_us;
90 __libc_lock_unlock (lock);
92 return l == NULL ? NULL : &l->fns[i];