Index: fusl/src/thread/pthread_atfork.c |
diff --git a/fusl/src/thread/pthread_atfork.c b/fusl/src/thread/pthread_atfork.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a40d7f63287079c2ce538360305b86e7174b06e9 |
--- /dev/null |
+++ b/fusl/src/thread/pthread_atfork.c |
@@ -0,0 +1,48 @@ |
+#include <pthread.h> |
+#include "libc.h" |
+ |
+static struct atfork_funcs { |
+ void (*prepare)(void); |
+ void (*parent)(void); |
+ void (*child)(void); |
+ struct atfork_funcs *prev, *next; |
+} *funcs; |
+ |
+static volatile int lock[2]; |
+ |
+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 -1; |
+ |
+ 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; |
+} |