* stdlib/Makefile (routines): Add quick_exit, at_quick_exit, and

cxa_at_quick_exit.
	(static-only-routines): Add at_quick_exit.
	* stdlib/Versions: Export quick_exit and __cxa_at_quick_exit for
	GLIBC_2.10.
	* stdlib/quick_exit.c: New file.
	* stdlib/at_quick_exit.c: New file.
	* stdlib/cxa_at_quick_exit.c: New file.
	* stdlib/cxa_atexit.c (__cxa_atexit): Move body to new function.  Call
	it appropriately.
	(__internal_atexit): New function.
	(__new_exitfn): Now takes parameter to point to the list to use.
	* stdlib/cxa_finalize.c: Remove quick_exit handlers, don't call them.
	* stdlib/exit.c (__run_exit_handlers): New function.  Split from...
	(exit): ...here.  Just call __run_exit_handlers appropriately.
	* stdlib/exit.h: Declare __quick_exit_funcs, __run_exit_handlers,
	__internal_atexit, __cxa_at_quick_exit.  Adjust __new_exitfn.
	* stdlib/on_exit.c: Adjust call to __new_exitfn.
	* stdlib/stdlib.h: Declare at_quick_exit and quick_exit.
This commit is contained in:
Ulrich Drepper 2009-03-08 19:53:12 +00:00
parent 130ca12eb3
commit 610e67ed5a
13 changed files with 232 additions and 30 deletions

View File

@ -1,5 +1,25 @@
2009-03-08 Ulrich Drepper <drepper@redhat.com>
* stdlib/Makefile (routines): Add quick_exit, at_quick_exit, and
cxa_at_quick_exit.
(static-only-routines): Add at_quick_exit.
* stdlib/Versions: Export quick_exit and __cxa_at_quick_exit for
GLIBC_2.10.
* stdlib/quick_exit.c: New file.
* stdlib/at_quick_exit.c: New file.
* stdlib/cxa_at_quick_exit.c: New file.
* stdlib/cxa_atexit.c (__cxa_atexit): Move body to new function. Call
it appropriately.
(__internal_atexit): New function.
(__new_exitfn): Now takes parameter to point to the list to use.
* stdlib/cxa_finalize.c: Remove quick_exit handlers, don't call them.
* stdlib/exit.c (__run_exit_handlers): New function. Split from...
(exit): ...here. Just call __run_exit_handlers appropriately.
* stdlib/exit.h: Declare __quick_exit_funcs, __run_exit_handlers,
__internal_atexit, __cxa_at_quick_exit. Adjust __new_exitfn.
* stdlib/on_exit.c: Adjust call to __new_exitfn.
* stdlib/stdlib.h: Declare at_quick_exit and quick_exit.
* po/id.po: Update from translation team.
2009-03-07 Ulrich Drepper <drepper@redhat.com>

5
NEWS
View File

@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2009-2-26
GNU C Library NEWS -- history of user-visible changes. 2009-3-8
Copyright (C) 1992-2008, 2009 Free Software Foundation, Inc.
See the end for copying conditions.
@ -18,6 +18,9 @@ Version 2.10
* New POSIX 2008 interface: psiginfo
Implemented by Ulrich Drepper.
* New ISO C++1x interfaces: quick_exit, at_quick_exit
Implemented by Ulrich Drepper.
Version 2.9

View File

@ -1,4 +1,4 @@
# Copyright (C) 1991-2006, 2007, 2008 Free Software Foundation, Inc.
# Copyright (C) 1991-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@ -34,6 +34,7 @@ routines := \
bsearch qsort msort \
getenv putenv setenv secure-getenv \
exit on_exit atexit cxa_atexit cxa_finalize old_atexit \
quick_exit at_quick_exit cxa_at_quick_exit \
abs labs llabs \
div ldiv lldiv \
mblen mbstowcs mbtowc wcstombs wctomb \
@ -57,7 +58,7 @@ aux = grouping groupingwc tens_in_limb
# These routines will be omitted from the libc shared object.
# Instead the static object files will be included in a special archive
# linked against when the shared library will be used.
static-only-routines = atexit
static-only-routines = atexit at_quick_exit
distribute := exit.h grouping.h abort-instr.h isomac.c tst-fmtmsg.sh \
allocalim.h

View File

@ -97,6 +97,9 @@ libc {
GLIBC_2.8 {
qsort_r;
}
GLIBC_2.10 {
quick_exit; __cxa_at_quick_exit;
}
GLIBC_PRIVATE {
# functions which have an additional interface since they are
# are cancelable.

50
stdlib/at_quick_exit.c Normal file
View File

@ -0,0 +1,50 @@
/* Copyright (C) 1991,1996,1999,2001,2006,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
In addition to the permissions in the GNU Lesser General Public
License, the Free Software Foundation gives you unlimited
permission to link the compiled version of this file with other
programs, and to distribute those programs without any restriction
coming from the use of this file. (The GNU Lesser General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into another program.)
Note that people who make modified versions of this file are not
obligated to grant this special exception for their modified
versions; it is their choice whether to do so. The GNU Lesser
General Public License gives permission to release a modified
version without this exception; this exception also makes it
possible to release a modified version which carries forward this
exception.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <stdlib.h>
#include "exit.h"
/* This is defined by newer gcc version unique for each module. */
extern void *__dso_handle __attribute__ ((__weak__));
/* Register FUNC to be executed by `quick_exit'. */
int
at_quick_exit (void (*func) (void))
{
return __cxa_at_quick_exit ((void (*) (void *)) func,
&__dso_handle == NULL ? NULL : __dso_handle);
}

View File

@ -0,0 +1,32 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <stdlib.h>
#include "exit.h"
static struct exit_function_list initial_quick;
struct exit_function_list *__quick_exit_funcs = &initial_quick;
/* Register a function to be called by quick_exit. */
int
attribute_hidden
__cxa_at_quick_exit (void (*func) (void *), void *d)
{
return __internal_atexit (func, NULL, d, &__quick_exit_funcs);
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1999, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
/* Copyright (C) 1999,2001,2002,2005,2006,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -26,13 +26,13 @@
#undef __cxa_atexit
/* Register a function to be called by exit or when a shared library
is unloaded. This function is only called from code generated by
the C++ compiler. */
int
__cxa_atexit (void (*func) (void *), void *arg, void *d)
attribute_hidden
__internal_atexit (void (*func) (void *), void *arg, void *d,
struct exit_function_list **listp)
{
struct exit_function *new = __new_exitfn ();
struct exit_function *new = __new_exitfn (listp);
if (new == NULL)
return -1;
@ -47,6 +47,16 @@ __cxa_atexit (void (*func) (void *), void *arg, void *d)
new->flavor = ef_cxa;
return 0;
}
/* Register a function to be called by exit or when a shared library
is unloaded. This function is only called from code generated by
the C++ compiler. */
int
__cxa_atexit (void (*func) (void *), void *arg, void *d)
{
return __internal_atexit (func, arg, d, &__exit_funcs);
}
INTDEF(__cxa_atexit)
@ -59,7 +69,7 @@ struct exit_function_list *__exit_funcs = &initial;
uint64_t __new_exitfn_called;
struct exit_function *
__new_exitfn (void)
__new_exitfn (struct exit_function_list **listp)
{
struct exit_function_list *p = NULL;
struct exit_function_list *l;
@ -68,7 +78,7 @@ __new_exitfn (void)
__libc_lock_lock (lock);
for (l = __exit_funcs; l != NULL; p = l, l = l->next)
for (l = *listp; l != NULL; p = l, l = l->next)
{
for (i = l->idx; i > 0; --i)
if (l->fns[i - 1].flavor != ef_free)
@ -92,8 +102,8 @@ __new_exitfn (void)
calloc (1, sizeof (struct exit_function_list));
if (p != NULL)
{
p->next = __exit_funcs;
__exit_funcs = p;
p->next = *listp;
*listp = p;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1999,2001,2002,2003,2005,2006 Free Software Foundation, Inc.
/* Copyright (C) 1999,2001-2003,2005,2006,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -63,6 +63,16 @@ __cxa_finalize (void *d)
}
}
/* Also remove the quick_exit handlers, but do not call them. */
for (funcs = __quick_exit_funcs; funcs; funcs = funcs->next)
{
struct exit_function *f;
for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
if (d == NULL || d == f->func.cxa.dso_handle)
f->flavor = ef_free;
}
/* Remove the registered fork handlers. We do not have to
unregister anything if the program is going to terminate anyway. */
#ifdef UNREGISTER_ATFORK

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1991,95,96,97,99,2001,2002,2005 Free Software Foundation, Inc.
/* Copyright (C) 1991,95,96,97,99,2001,2002,2005,2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -30,20 +31,22 @@ DEFINE_HOOK (__libc_atexit, (void))
in the reverse of the order in which they were registered
perform stdio cleanup, and terminate program execution with STATUS. */
void
exit (int status)
attribute_hidden
__run_exit_handlers (int status, struct exit_function_list **listp,
bool run_list_atexit)
{
/* We do it this way to handle recursive calls to exit () made by
the functions registered with `atexit' and `on_exit'. We call
everyone on the list and use the status value in the last
exit (). */
while (__exit_funcs != NULL)
while (*listp != NULL)
{
struct exit_function_list *old;
struct exit_function_list *cur = *listp;
while (__exit_funcs->idx > 0)
while (cur->idx > 0)
{
const struct exit_function *const f =
&__exit_funcs->fns[--__exit_funcs->idx];
&cur->fns[--cur->idx];
switch (f->flavor)
{
void (*atfct) (void);
@ -77,16 +80,23 @@ exit (int status)
}
}
old = __exit_funcs;
__exit_funcs = __exit_funcs->next;
if (__exit_funcs != NULL)
*listp = cur->next;
if (*listp != NULL)
/* Don't free the last element in the chain, this is the statically
allocate element. */
free (old);
free (cur);
}
if (run_list_atexit)
RUN_HOOK (__libc_atexit, ());
_exit (status);
}
void
exit (int status)
{
__run_exit_handlers (status, __exit_funcs, true);
}
libc_hidden_def (exit)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991,1996,1997,1999,2001,2002,2006
/* Copyright (C) 1991,1996,1997,1999,2001,2002,2006,2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@ -20,6 +20,7 @@
#ifndef _EXIT_H
#define _EXIT_H 1
#include <stdbool.h>
#include <stdint.h>
enum
@ -59,8 +60,19 @@ struct exit_function_list
struct exit_function fns[32];
};
extern struct exit_function_list *__exit_funcs attribute_hidden;
extern struct exit_function_list *__quick_exit_funcs attribute_hidden;
extern struct exit_function *__new_exitfn (void);
extern struct exit_function *__new_exitfn (struct exit_function_list **listp);
extern uint64_t __new_exitfn_called attribute_hidden;
extern void __run_exit_handlers (int status, struct exit_function_list **listp,
bool run_list_atexit) attribute_hidden;
extern int __internal_atexit (void (*func) (void *), void *arg, void *d,
struct exit_function_list **listp)
attribute_hidden;
extern int __cxa_at_quick_exit (void (*func) (void *), void *d)
attribute_hidden;
#endif /* exit.h */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1996, 2005 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1996, 2005, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -25,7 +25,7 @@
int
__on_exit (void (*func) (int status, void *arg), void *arg)
{
struct exit_function *new = __new_exitfn ();
struct exit_function *new = __new_exitfn (&__exit_funcs);
if (new == NULL)
return -1;

30
stdlib/quick_exit.c Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sysdep.h>
#include "exit.h"
void
quick_exit (int status)
{
__run_exit_handlers (status, __quick_exit_funcs, false);
}

View File

@ -515,6 +515,18 @@ extern void abort (void) __THROW __attribute__ ((__noreturn__));
/* Register a function to be called when `exit' is called. */
extern int atexit (void (*__func) (void)) __THROW __nonnull ((1));
#ifdef __USE_GNU
// XXX There should be a macro to signal with C++ revision is used.
// XXX This function is in the C++1x revision.
/* Register a function to be called when `quick_exit' is called. */
# ifdef __cplusplus
extern "C++" int at_quick_exit (void (*__func) (void))
__THROW __asm ("at_quick_exit") __nonnull ((1));
# else
extern int at_quick_exit (void (*__func) (void)) __THROW __nonnull ((1));
# endif
#endif
__END_NAMESPACE_STD
#ifdef __USE_MISC
@ -526,9 +538,18 @@ extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg)
__BEGIN_NAMESPACE_STD
/* Call all functions registered with `atexit' and `on_exit',
in the reverse of the order in which they were registered
in the reverse of the order in which they were registered,
perform stdio cleanup, and terminate program execution with STATUS. */
extern void exit (int __status) __THROW __attribute__ ((__noreturn__));
#ifdef __USE_GNU
// XXX There should be a macro to signal with C++ revision is used.
// XXX This function is in the C++1x revision.
/* Call all functions registered with `at_quick_exit' in the reverse
of the order in which they were registered and terminate program
execution with STATUS. */
extern void quick_exit (int __status) __THROW __attribute__ ((__noreturn__));
#endif
__END_NAMESPACE_STD
#ifdef __USE_ISOC99