Merge branch 'vendor/GDB'
[dragonfly.git] / lib / libc / stdlib / quick_exit.c
1
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 #include "libc_private.h"
6 #include "spinlock.h"
7
8
9 struct quick_exit_fn {
10        struct quick_exit_fn    *next;
11        void                    (*func)(void);
12 };
13
14 static struct quick_exit_fn *quick_exit_fns;
15 static spinlock_t quick_exit_spinlock;
16
17 /*
18  * at_quick_exit:
19  *
20  *     Register a function to be called at quick_exit.
21  */
22 int
23 at_quick_exit(void (*func)(void))
24 {
25        struct quick_exit_fn *fn;
26
27        fn = malloc(sizeof(struct quick_exit_fn));
28        if (!fn)
29                return (-1);
30
31        fn->func = func;
32
33        if (__isthreaded)
34                _SPINLOCK(&quick_exit_spinlock);
35        
36        fn->next = quick_exit_fns;
37        quick_exit_fns = fn;
38
39        if (__isthreaded)
40                _SPINUNLOCK(&quick_exit_spinlock);
41
42        return (0);
43 }
44
45 /*
46  * quick_exit:
47  *
48  *     Abandon a process. Execute all quick_exit handlers.
49  */
50 void
51 quick_exit(int status)
52 {
53        struct quick_exit_fn *fn;
54
55        if (__isthreaded)
56                _SPINLOCK(&quick_exit_spinlock);
57        for (fn = quick_exit_fns; fn != NULL; fn = fn->next) {
58                fn->func();
59        }
60        if (__isthreaded)
61                _SPINUNLOCK(&quick_exit_spinlock);
62
63        _exit(status);
64 }