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