On Wed, Dec 07, 2011 at 03:25:48PM +0000, David Chisnall wrote: > Author: theraven > Date: Wed Dec 7 15:25:48 2011 > New Revision: 228322 > URL: http://svn.freebsd.org/changeset/base/228322 > > Log: > Implement quick_exit() / at_quick_exit() from C++11 / C1x. Also add a > __noreturn macro and modify the other exiting functions to use it. > > The __noreturn macro, unlike __dead2, must be used BEFORE the function. > This is in line with the C and C++ specifications that place _Noreturn (c1x) > and [[noreturn]] (C++11) in front of the functions. As with __dead2, this > macro falls back to using the GCC attribute. > > Unfortunately, clang currently sets the same value for the C version macro > in C99 and C1x modes, so these functions are hidden by default. At some > point before 10.0, I need to go through the headers and clean up the C1x / > C++11 visibility. > > Reviewed by: brooks (mentor) And, was it approved ?
> +#include <stdlib.h> > +#include <pthread.h> > + > +/** > + * Linked list of quick exit handlers. This is simpler than the atexit() > + * version, because it is not required to support C++ destructors or > + * DSO-specific cleanups. > + */ > +struct quick_exit_handler { > + struct quick_exit_handler *next; > + void (*cleanup)(void); > +}; > + > +__attribute((weak)) > +void _ZSt9terminatev(void); Why do you need this ? You are not calling terminate() anyway, and added an explicit comment. > + > +/** > + * Lock protecting the handlers list. > + */ > +static pthread_mutex_t atexit_mutex = PTHREAD_MUTEX_INITIALIZER; > +/** > + * Stack of cleanup handlers. These will be invoked in reverse order when > + */ > +static struct quick_exit_handler *handlers; > + > +int > +at_quick_exit(void (*func)(void)) > +{ > + struct quick_exit_handler *h = malloc(sizeof(struct > quick_exit_handler)); You are making initialization at the declaration place, which is not recommended by style. > + > + if (0 == h) { Why 0 and not NULL ? Later, you use NULL. The {} are not needed. > + return 1; This shall be return (1); > + } > + h->cleanup = func; > + pthread_mutex_lock(&atexit_mutex); Note that libc code is careful to only call pthread mutex functions if __isthreaded variable is set. Also note that libc uses mangled names to allow the application interposition of the functions. E.g. ANSI C code is allowed to have pthread_mutex_lock() function defined. > + h->next = handlers; > + handlers = h; > + pthread_mutex_unlock(&atexit_mutex); > + return 0; And this shall be return (0); > +} > + > +void quick_exit(int status) The function name shall start at the column 0. > +{ > + /* > + * XXX: The C++ spec requires us to call std::terminate if there is an > + * exception here. > + */ > + for (struct quick_exit_handler *h = handlers ; NULL != h ; h = h->next) This fragment violates so many style requirements that I probably fail to enumerate them all. The h declaration shall go at the start of function, and not at the for statement. The opening '{' shall be placed on the line of 'for'. More, the {} bracing is not needed there. No space is needed before ';', three times. > + { > + h->cleanup(); > + } > + _Exit(status); > +}
pgp3MVIV7Qt7q.pgp
Description: PGP signature