pthread_atfork.c raw

   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  }
  50