From 4abab5ad6c8465a7528ccdd5f49367da05f78bbd Mon Sep 17 00:00:00 2001 From: Vladimir Azarov Date: Tue, 1 Oct 2024 15:47:05 +0200 Subject: Initial version --- src/thread/pthread_atfork.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/thread/pthread_atfork.c (limited to 'src/thread/pthread_atfork.c') diff --git a/src/thread/pthread_atfork.c b/src/thread/pthread_atfork.c new file mode 100644 index 0000000..26d3254 --- /dev/null +++ b/src/thread/pthread_atfork.c @@ -0,0 +1,55 @@ +#include +#include +#include "libc.h" +#include "lock.h" + +#define malloc __libc_malloc +#define calloc undef +#define realloc undef +#define free undef + +static struct atfork_funcs { + void (*prepare)(void); + void (*parent)(void); + void (*child)(void); + struct atfork_funcs *prev, *next; +} *funcs; + +static volatile int lock[1]; + +void __fork_handler(int who) +{ + struct atfork_funcs *p; + if (!funcs) return; + if (who < 0) { + LOCK(lock); + for (p=funcs; p; p = p->next) { + if (p->prepare) p->prepare(); + funcs = p; + } + } else { + for (p=funcs; p; p = p->prev) { + if (!who && p->parent) p->parent(); + else if (who && p->child) p->child(); + funcs = p; + } + UNLOCK(lock); + } +} + +int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) +{ + struct atfork_funcs *new = malloc(sizeof *new); + if (!new) return ENOMEM; + + LOCK(lock); + new->next = funcs; + new->prev = 0; + new->prepare = prepare; + new->parent = parent; + new->child = child; + if (funcs) funcs->prev = new; + funcs = new; + UNLOCK(lock); + return 0; +} -- cgit v1.2.3