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