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);
> +}

Attachment: pgp3MVIV7Qt7q.pgp
Description: PGP signature

Reply via email to