Index: libc/gen/_pthread_stubs.c =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/_pthread_stubs.c,v retrieving revision 1.13 diff -u -r1.13 _pthread_stubs.c --- libc/gen/_pthread_stubs.c 5 Mar 2006 18:10:27 -0000 1.13 +++ libc/gen/_pthread_stubs.c 10 Mar 2006 10:08:25 -0000 @@ -55,12 +55,15 @@ static int stub_zero(void); static int stub_true(void); static void stub_exit(void); +static void stub_void(void); #define PJT_DUAL_ENTRY(entry) \ (pthread_func_t)entry, (pthread_func_t)entry pthread_func_entry_t __thr_jtable[PJT_MAX] = { {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_ATFORK */ + {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_ATFORK_NP */ + {PJT_DUAL_ENTRY(stub_void)}, /* PJT_ATFORK_UNREGISTER_NP */ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_ATTR_DESTROY */ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_ATTR_GETDETACHSTATE */ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_ATTR_GETGUARDSIZE */ @@ -206,6 +209,27 @@ return (func(p0, p1, p2)); \ } +#define STUB_FUNC4(name, idx, ret, p0_type, p1_type, p2_type, p3_type) \ + static ret FUNC_EXP(name)(p0_type, p1_type, p2_type, p3_type) __used; \ + static ret FUNC_INT(name)(p0_type, p1_type, p2_type, p3_type) __used; \ + WEAK_REF(FUNC_EXP(name), name); \ + WEAK_REF(FUNC_INT(name), __CONCAT(_, name)); \ + typedef ret (*FUNC_TYPE(name))(p0_type, p1_type, p2_type, p3_type); \ + static ret FUNC_EXP(name)(p0_type p0, p1_type p1, p2_type p2, \ + p3_type p3) \ + { \ + FUNC_TYPE(name) func; \ + func = (FUNC_TYPE(name))__thr_jtable[idx][0]; \ + return (func(p0, p1, p2, p3)); \ + } \ + static ret FUNC_INT(name)(p0_type p0, p1_type p1, p2_type p2, \ + p3_type p3) \ + { \ + FUNC_TYPE(name) func; \ + func = (FUNC_TYPE(name))__thr_jtable[idx][1]; \ + return (func(p0, p1, p2, p3)); \ + } + STUB_FUNC1(pthread_cond_broadcast, PJT_COND_BROADCAST, int, void *) STUB_FUNC1(pthread_cond_destroy, PJT_COND_DESTROY, int, void *) STUB_FUNC2(pthread_cond_init, PJT_COND_INIT, int, void *, void *) @@ -235,6 +259,8 @@ STUB_FUNC2(pthread_setspecific, PJT_SETSPECIFIC, int, pthread_key_t, void *) STUB_FUNC3(pthread_sigmask, PJT_SIGMASK, int, int, void *, void *) STUB_FUNC3(pthread_atfork, PJT_ATFORK, int, void *, void *, void*) +STUB_FUNC4(pthread_atfork_np, PJT_ATFORK_NP, int, void *, void *, void *, void*); +STUB_FUNC1(pthread_atfork_unregister_np, PJT_ATFORK_UNREGISTER_NP, void, void *); STUB_FUNC1(pthread_attr_destroy, PJT_ATTR_DESTROY, int, void *); STUB_FUNC2(pthread_attr_getdetachstate, PJT_ATTR_GETDETACHSTATE, int, void *, void *) STUB_FUNC2(pthread_attr_getguardsize, PJT_ATTR_GETGUARDSIZE, int, void *, void *) @@ -301,3 +327,8 @@ { exit(0); } + +static void +stub_void(void) +{ +} Index: libc/include/libc_private.h =================================================================== RCS file: /home/ncvs/src/lib/libc/include/libc_private.h,v retrieving revision 1.15 diff -u -r1.15 libc_private.h --- libc/include/libc_private.h 5 Mar 2006 18:10:28 -0000 1.15 +++ libc/include/libc_private.h 10 Mar 2006 10:08:25 -0000 @@ -71,6 +71,8 @@ */ typedef enum { PJT_ATFORK, + PJT_ATFORK_NP, + PJT_ATFORK_UNREGISTER_NP, PJT_ATTR_DESTROY, PJT_ATTR_GETDETACHSTATE, PJT_ATTR_GETGUARDSIZE, Index: libc/include/namespace.h =================================================================== RCS file: /home/ncvs/src/lib/libc/include/namespace.h,v retrieving revision 1.18 diff -u -r1.18 namespace.h --- libc/include/namespace.h 5 Mar 2006 18:10:28 -0000 1.18 +++ libc/include/namespace.h 10 Mar 2006 10:08:25 -0000 @@ -82,6 +82,8 @@ #define open _open #define poll _poll #define pthread_atfork _pthread_atfork +#define pthread_atfork_np _pthread_atfork_np +#define pthread_atfork_unregister_np _pthread_atfork_unregister_np #define pthread_attr_destroy _pthread_attr_destroy #define pthread_attr_getdetachstate _pthread_attr_getdetachstate #define pthread_attr_getguardsize _pthread_attr_getguardsize Index: libc/include/un-namespace.h =================================================================== RCS file: /home/ncvs/src/lib/libc/include/un-namespace.h,v retrieving revision 1.15 diff -u -r1.15 un-namespace.h --- libc/include/un-namespace.h 10 Mar 2006 09:58:18 -0000 1.15 +++ libc/include/un-namespace.h 10 Mar 2006 10:08:25 -0000 @@ -63,6 +63,8 @@ #undef open #undef poll #undef pthread_atfork +#undef pthread_atfork_np +#undef pthread_atfork_unregister_np #undef pthread_attr_destroy #undef pthread_attr_getdetachstate #undef pthread_attr_getguardsize Index: libpthread/pthread.map =================================================================== RCS file: /home/ncvs/src/lib/libpthread/pthread.map,v retrieving revision 1.16 diff -u -r1.16 pthread.map --- libpthread/pthread.map 24 Oct 2005 05:37:21 -0000 1.16 +++ libpthread/pthread.map 10 Mar 2006 10:08:32 -0000 @@ -32,6 +32,8 @@ _pause; _pselect; _pthread_atfork; + _pthread_atfork_np; + _pthread_atfork_unregister_np; _pthread_barrier_destroy; _pthread_barrier_init; _pthread_barrier_wait; @@ -194,6 +196,8 @@ poll; pselect; pthread_atfork; + pthread_atfork_np; + pthread_atfork_unregister_np; pthread_barrier_destroy; pthread_barrier_init; pthread_barrier_wait; Index: libpthread/thread/thr_atfork.c =================================================================== RCS file: /home/ncvs/src/lib/libpthread/thread/thr_atfork.c,v retrieving revision 1.1 diff -u -r1.1 thr_atfork.c --- libpthread/thread/thr_atfork.c 5 Nov 2003 03:42:10 -0000 1.1 +++ libpthread/thread/thr_atfork.c 10 Mar 2006 10:08:33 -0000 @@ -32,10 +32,12 @@ #include "thr_private.h" __weak_reference(_pthread_atfork, pthread_atfork); +__weak_reference(_pthread_atfork_np, pthread_atfork_np); +__weak_reference(_pthread_atfork_unregister_np, pthread_atfork_unregister_np); int -_pthread_atfork(void (*prepare)(void), void (*parent)(void), - void (*child)(void)) +_pthread_atfork_np(void *key, + void (*prepare)(void), void (*parent)(void), void (*child)(void)) { struct pthread_atfork *af; @@ -48,9 +50,38 @@ af->prepare = prepare; af->parent = parent; af->child = child; + af->key = key; _pthread_mutex_lock(&_thr_atfork_mutex); TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe); _pthread_mutex_unlock(&_thr_atfork_mutex); return (0); } +void +_pthread_atfork_unregister_np(void *key) +{ + struct pthread_atfork *af, *afn; + TAILQ_HEAD(atfork_head, pthread_atfork) worklist; + + TAILQ_INIT(&worklist); + _pthread_mutex_lock(&_thr_atfork_mutex); + TAILQ_FOREACH_SAFE(af, &_thr_atfork_list, qe, afn) { + if (af->key == key) { + TAILQ_REMOVE(&_thr_atfork_list, af, qe); + TAILQ_INSERT_HEAD(&worklist, af, qe); + } + } + _pthread_mutex_unlock(&_thr_atfork_mutex); + + while ((af = TAILQ_FIRST(&worklist)) != NULL) { + TAILQ_REMOVE(&worklist, af, qe); + free(af); + } +} + +int +_pthread_atfork(void (*prepare)(void), void (*parent)(void), + void (*child)(void)) +{ + return (_pthread_atfork_np(NULL, prepare, parent, child)); +} Index: libpthread/thread/thr_init.c =================================================================== RCS file: /home/ncvs/src/lib/libpthread/thread/thr_init.c,v retrieving revision 1.73 diff -u -r1.73 thr_init.c --- libpthread/thread/thr_init.c 6 Mar 2006 05:02:28 -0000 1.73 +++ libpthread/thread/thr_init.c 10 Mar 2006 10:08:33 -0000 @@ -163,6 +163,8 @@ static pthread_func_t jmp_table[][2] = { {DUAL_ENTRY(_pthread_atfork)}, /* PJT_ATFORK */ + {DUAL_ENTRY(_pthread_atfork_np)}, /* PJT_ATFORK_NP */ + {DUAL_ENTRY(_pthread_atfork_unregister_np)}, /* PJT_ATFORK_UNREGISTER_NP */ {DUAL_ENTRY(_pthread_attr_destroy)}, /* PJT_ATTR_DESTROY */ {DUAL_ENTRY(_pthread_attr_getdetachstate)}, /* PJT_ATTR_GETDETACHSTATE */ {DUAL_ENTRY(_pthread_attr_getguardsize)}, /* PJT_ATTR_GETGUARDSIZE */ Index: libpthread/thread/thr_private.h =================================================================== RCS file: /home/ncvs/src/lib/libpthread/thread/thr_private.h,v retrieving revision 1.124 diff -u -r1.124 thr_private.h --- libpthread/thread/thr_private.h 6 Mar 2006 05:02:28 -0000 1.124 +++ libpthread/thread/thr_private.h 10 Mar 2006 10:08:35 -0000 @@ -440,6 +440,7 @@ void (*prepare)(void); void (*parent)(void); void (*child)(void); + void *key; }; struct pthread_attr { Index: libthr/pthread.map =================================================================== RCS file: /home/ncvs/src/lib/libthr/pthread.map,v retrieving revision 1.13 diff -u -r1.13 pthread.map --- libthr/pthread.map 8 Mar 2006 23:47:04 -0000 1.13 +++ libthr/pthread.map 10 Mar 2006 10:08:36 -0000 @@ -36,6 +36,8 @@ _pause; _pselect; _pthread_atfork; + _pthread_atfork_np; + _pthread_atfork_unregister_np; _pthread_barrier_destroy; _pthread_barrier_init; _pthread_barrier_wait; @@ -198,6 +200,8 @@ poll; pselect; pthread_atfork; + pthread_atfork_np; + pthread_atfork_unregister_np; pthread_barrier_destroy; pthread_barrier_init; pthread_barrier_wait; Index: libthr/thread/thr_fork.c =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_fork.c,v retrieving revision 1.3 diff -u -r1.3 thr_fork.c --- libthr/thread/thr_fork.c 12 Jan 2006 07:28:21 -0000 1.3 +++ libthr/thread/thr_fork.c 10 Mar 2006 10:08:36 -0000 @@ -71,10 +71,12 @@ #include "thr_private.h" __weak_reference(_pthread_atfork, pthread_atfork); +__weak_reference(_pthread_atfork_np, pthread_atfork_np); +__weak_reference(_pthread_atfork_unregister_np, pthread_atfork_unregister_np); int -_pthread_atfork(void (*prepare)(void), void (*parent)(void), - void (*child)(void)) +_pthread_atfork_np(void *key, + void (*prepare)(void), void (*parent)(void), void (*child)(void)) { struct pthread *curthread; struct pthread_atfork *af; @@ -88,12 +90,44 @@ af->prepare = prepare; af->parent = parent; af->child = child; + af->key = key; THR_UMTX_LOCK(curthread, &_thr_atfork_lock); TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe); THR_UMTX_UNLOCK(curthread, &_thr_atfork_lock); return (0); } +void +_pthread_atfork_unregister_np(void *key) +{ + struct pthread *curthread; + struct pthread_atfork *af, *afn; + TAILQ_HEAD(atfork_head, pthread_atfork) worklist; + + curthread = _get_curthread(); + TAILQ_INIT(&worklist); + THR_UMTX_LOCK(curthread, &_thr_atfork_lock); + TAILQ_FOREACH_SAFE(af, &_thr_atfork_list, qe, afn) { + if (af->key == key) { + TAILQ_REMOVE(&_thr_atfork_list, af, qe); + TAILQ_INSERT_HEAD(&worklist, af, qe); + } + } + THR_UMTX_UNLOCK(curthread, &_thr_atfork_lock); + + while ((af = TAILQ_FIRST(&worklist)) != NULL) { + TAILQ_REMOVE(&worklist, af, qe); + free(af); + } +} + +int +_pthread_atfork(void (*prepare)(void), void (*parent)(void), + void (*child)(void)) +{ + return (_pthread_atfork_np(NULL, prepare, parent, child)); +} + __weak_reference(_fork, fork); pid_t Index: libthr/thread/thr_init.c =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_init.c,v retrieving revision 1.30 diff -u -r1.30 thr_init.c --- libthr/thread/thr_init.c 5 Mar 2006 18:10:28 -0000 1.30 +++ libthr/thread/thr_init.c 10 Mar 2006 10:08:38 -0000 @@ -199,6 +199,8 @@ static pthread_func_t jmp_table[][2] = { {DUAL_ENTRY(_pthread_atfork)}, /* PJT_ATFORK */ + {DUAL_ENTRY(_pthread_atfork_np)}, /* PJT_ATFORK_NP */ + {DUAL_ENTRY(_pthread_atfork_unregister_np)}, /* PJT_ATFORK_UNREGISTER_NP */ {DUAL_ENTRY(_pthread_attr_destroy)}, /* PJT_ATTR_DESTROY */ {DUAL_ENTRY(_pthread_attr_getdetachstate)}, /* PJT_ATTR_GETDETACHSTATE */ {DUAL_ENTRY(_pthread_attr_getguardsize)}, /* PJT_ATTR_GETGUARDSIZE */ Index: libthr/thread/thr_private.h =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_private.h,v retrieving revision 1.57 diff -u -r1.57 thr_private.h --- libthr/thread/thr_private.h 15 Feb 2006 23:05:03 -0000 1.57 +++ libthr/thread/thr_private.h 10 Mar 2006 10:08:38 -0000 @@ -228,6 +228,7 @@ void (*prepare)(void); void (*parent)(void); void (*child)(void); + void *key; }; struct pthread_attr {