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