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