use libc-internal malloc for pthread_atfork
[musl] / src / thread / pthread_atfork.c
1 #include <pthread.h>
2 #include <errno.h>
3 #include "libc.h"
4 #include "lock.h"
5
6 #define malloc __libc_malloc
7 #define calloc undef
8 #define realloc undef
9 #define free undef
10
11 static struct atfork_funcs {
12         void (*prepare)(void);
13         void (*parent)(void);
14         void (*child)(void);
15         struct atfork_funcs *prev, *next;
16 } *funcs;
17
18 static volatile int lock[1];
19
20 void __fork_handler(int who)
21 {
22         struct atfork_funcs *p;
23         if (!funcs) return;
24         if (who < 0) {
25                 LOCK(lock);
26                 for (p=funcs; p; p = p->next) {
27                         if (p->prepare) p->prepare();
28                         funcs = p;
29                 }
30         } else {
31                 for (p=funcs; p; p = p->prev) {
32                         if (!who && p->parent) p->parent();
33                         else if (who && p->child) p->child();
34                         funcs = p;
35                 }
36                 UNLOCK(lock);
37         }
38 }
39
40 int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
41 {
42         struct atfork_funcs *new = malloc(sizeof *new);
43         if (!new) return ENOMEM;
44
45         LOCK(lock);
46         new->next = funcs;
47         new->prev = 0;
48         new->prepare = prepare;
49         new->parent = parent;
50         new->child = child;
51         if (funcs) funcs->prev = new;
52         funcs = new;
53         UNLOCK(lock);
54         return 0;
55 }