Back to index

glibc  2.9
cxa_finalize.c
Go to the documentation of this file.
00001 /* Copyright (C) 1999,2001,2002,2003,2005,2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <assert.h>
00020 #include <stdlib.h>
00021 #include <atomic.h>
00022 #include "exit.h"
00023 #include <fork.h>
00024 #include <sysdep.h>
00025 
00026 /* If D is non-NULL, call all functions registered with `__cxa_atexit'
00027    with the same dso handle.  Otherwise, if D is NULL, call all of the
00028    registered handlers.  */
00029 void
00030 __cxa_finalize (void *d)
00031 {
00032   struct exit_function_list *funcs;
00033 
00034  restart:
00035   for (funcs = __exit_funcs; funcs; funcs = funcs->next)
00036     {
00037       struct exit_function *f;
00038 
00039       for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
00040        {
00041          void (*cxafn) (void *arg, int status);
00042          void *cxaarg;
00043 
00044          if ((d == NULL || d == f->func.cxa.dso_handle)
00045              /* We don't want to run this cleanup more than once.  */
00046              && (cxafn = f->func.cxa.fn,
00047                 cxaarg = f->func.cxa.arg,
00048                 ! catomic_compare_and_exchange_bool_acq (&f->flavor, ef_free,
00049                                                     ef_cxa)))
00050            {
00051              uint64_t check = __new_exitfn_called;
00052 
00053 #ifdef PTR_DEMANGLE
00054              PTR_DEMANGLE (cxafn);
00055 #endif
00056              cxafn (cxaarg, 0);
00057 
00058              /* It is possible that that last exit function registered
00059                more exit functions.  Start the loop over.  */
00060              if (__builtin_expect (check != __new_exitfn_called, 0))
00061               goto restart;
00062            }
00063        }
00064     }
00065 
00066   /* Remove the registered fork handlers.  We do not have to
00067      unregister anything if the program is going to terminate anyway.  */
00068 #ifdef UNREGISTER_ATFORK
00069   if (d != NULL)
00070     UNREGISTER_ATFORK (d);
00071 #endif
00072 }