From 808851ae6706df827175585557af755127ca3553 Mon Sep 17 00:00:00 2001 From: Hasso Tepper Date: Sun, 25 May 2008 21:34:49 +0000 Subject: [PATCH] Add pthread_atfork() implementation to libc_r. libthread_xu has it already, but it was unusable due to missing code in libc_r. Obtained-from: FreeBSD --- lib/libc/gen/pthread_fake.c | 3 +- lib/libc_r/uthread/Makefile.inc | 3 +- lib/libc_r/uthread/pthread_private.h | 12 +++++- lib/libc_r/uthread/uthread_atfork.c | 56 ++++++++++++++++++++++++++++ lib/libc_r/uthread/uthread_fork.c | 24 +++++++++++- lib/libc_r/uthread/uthread_init.c | 4 +- 6 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 lib/libc_r/uthread/uthread_atfork.c diff --git a/lib/libc/gen/pthread_fake.c b/lib/libc/gen/pthread_fake.c index dd2d989c30..7b28929f8b 100644 --- a/lib/libc/gen/pthread_fake.c +++ b/lib/libc/gen/pthread_fake.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/lib/libc/gen/pthread_fake.c,v 1.2 2005/04/26 08:41:44 joerg Exp $ + * $DragonFly: src/lib/libc/gen/pthread_fake.c,v 1.3 2008/05/25 21:34:49 hasso Exp $ */ #ifndef _THREAD_SAFE @@ -53,6 +53,7 @@ int _pthread_fake_inval(void); void *_pthread_fake_null(void); +__weak_reference(_pthread_fake_inval, pthread_atfork); __weak_reference(_pthread_fake_inval, pthread_attr_destroy); __weak_reference(_pthread_fake_inval, pthread_attr_get_np); __weak_reference(_pthread_fake_inval, pthread_attr_getdetachstate); diff --git a/lib/libc_r/uthread/Makefile.inc b/lib/libc_r/uthread/Makefile.inc index 59f287362b..1c79664ee4 100644 --- a/lib/libc_r/uthread/Makefile.inc +++ b/lib/libc_r/uthread/Makefile.inc @@ -1,5 +1,5 @@ # $FreeBSD: src/lib/libc_r/uthread/Makefile.inc,v 1.23.2.8 2003/05/27 18:18:01 jdp Exp $ -# $DragonFly: src/lib/libc_r/uthread/Makefile.inc,v 1.9 2005/05/11 12:59:58 davidxu Exp $ +# $DragonFly: src/lib/libc_r/uthread/Makefile.inc,v 1.10 2008/05/25 21:34:49 hasso Exp $ # uthread sources .PATH: ${.CURDIR}/uthread @@ -7,6 +7,7 @@ SRCS+= \ uthread_accept.c \ uthread_aio_suspend.c \ + uthread_atfork.c \ uthread_attr_destroy.c \ uthread_attr_get_np.c \ uthread_attr_init.c \ diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h index b4ef11554f..ceae8bab1c 100644 --- a/lib/libc_r/uthread/pthread_private.h +++ b/lib/libc_r/uthread/pthread_private.h @@ -32,7 +32,7 @@ * Private thread definitions for the uthread kernel. * * $FreeBSD: src/lib/libc_r/uthread/pthread_private.h,v 1.36.2.21 2002/10/22 14:44:02 fjoe Exp $ - * $DragonFly: src/lib/libc_r/uthread/pthread_private.h,v 1.15 2007/12/14 20:07:59 dillon Exp $ + * $DragonFly: src/lib/libc_r/uthread/pthread_private.h,v 1.16 2008/05/25 21:34:49 hasso Exp $ */ #ifndef _PTHREAD_PRIVATE_H @@ -372,6 +372,13 @@ struct pthread_cleanup { void *routine_arg; }; +struct pthread_atfork { + TAILQ_ENTRY(pthread_atfork) qe; + void (*prepare)(void); + void (*parent)(void); + void (*child)(void); +}; + struct pthread_attr { int sched_policy; int sched_inherit; @@ -935,6 +942,9 @@ SCLASS struct pthread *_thread_initial ; #endif +SCLASS TAILQ_HEAD(atfork_head, pthread_atfork) _atfork_list; +SCLASS pthread_mutex_t _atfork_mutex; + /* Default thread attributes: */ SCLASS struct pthread_attr pthread_attr_default #ifdef GLOBAL_PTHREAD_PRIVATE diff --git a/lib/libc_r/uthread/uthread_atfork.c b/lib/libc_r/uthread/uthread_atfork.c new file mode 100644 index 0000000000..de987e71b9 --- /dev/null +++ b/lib/libc_r/uthread/uthread_atfork.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2003 Daniel Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libpthread/thread/thr_atfork.c,v 1.1 2003/11/05 03:42:10 davidxu Exp $ + * $DragonFly: src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2008/05/25 21:34:49 hasso Exp $ + */ +#include +#include +#include +#include +#include "pthread_private.h" + +int +_pthread_atfork(void (*prepare)(void), void (*parent)(void), + void (*child)(void)) +{ + struct pthread_atfork *af; + + if (_thread_initial == NULL) + _thread_init(); + + if ((af = malloc(sizeof(struct pthread_atfork))) == NULL) + return (ENOMEM); + + af->prepare = prepare; + af->parent = parent; + af->child = child; + _pthread_mutex_lock(&_atfork_mutex); + TAILQ_INSERT_TAIL(&_atfork_list, af, qe); + _pthread_mutex_unlock(&_atfork_mutex); + return (0); +} + +__strong_reference(_pthread_atfork, pthread_atfork); diff --git a/lib/libc_r/uthread/uthread_fork.c b/lib/libc_r/uthread/uthread_fork.c index b933543dd4..b432dc6152 100644 --- a/lib/libc_r/uthread/uthread_fork.c +++ b/lib/libc_r/uthread/uthread_fork.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libc_r/uthread/uthread_fork.c,v 1.19.2.7 2002/10/22 14:44:03 fjoe Exp $ - * $DragonFly: src/lib/libc_r/uthread/uthread_fork.c,v 1.5 2006/08/03 16:40:46 swildner Exp $ + * $DragonFly: src/lib/libc_r/uthread/uthread_fork.c,v 1.6 2008/05/25 21:34:49 hasso Exp $ */ #include #include @@ -44,6 +44,7 @@ pid_t _fork(void) { struct pthread *curthread = _get_curthread(); + struct pthread_atfork *af; int i, flags; pid_t ret; pthread_t pthread; @@ -55,9 +56,22 @@ _fork(void) */ _thread_kern_sig_defer(); + _pthread_mutex_lock(&_atfork_mutex); + + /* Run down atfork prepare handlers. */ + TAILQ_FOREACH_REVERSE(af, &_atfork_list, atfork_head, qe) { + if (af->prepare != NULL) + af->prepare(); + } + /* Fork a new process: */ if ((ret = __sys_fork()) != 0) { - /* Parent process or error. Nothing to do here. */ + /* Run down atfork parent handlers. */ + TAILQ_FOREACH(af, &_atfork_list, qe) { + if (af->parent != NULL) + af->parent(); + } + _pthread_mutex_unlock(&_atfork_mutex); } else { /* Close the pthread kernel pipe: */ __sys_close(_thread_kern_pipe[0]); @@ -182,6 +196,12 @@ _fork(void) } } } + /* Run down atfork child handlers. */ + TAILQ_FOREACH(af, &_atfork_list, qe) { + if (af->child != NULL) + af->child(); + } + _mutex_reinit(&_atfork_mutex); } /* diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c index 517bae69c5..25d1cb05ec 100644 --- a/lib/libc_r/uthread/uthread_init.c +++ b/lib/libc_r/uthread/uthread_init.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libc_r/uthread/uthread_init.c,v 1.23.2.11 2003/02/24 23:27:32 das Exp $ - * $DragonFly: src/lib/libc_r/uthread/uthread_init.c,v 1.10 2007/04/29 01:10:33 dillon Exp $ + * $DragonFly: src/lib/libc_r/uthread/uthread_init.c,v 1.11 2008/05/25 21:34:49 hasso Exp $ */ /* Allocate space for global thread variables here: */ @@ -292,6 +292,8 @@ _thread_init(void) TAILQ_INIT(&_thread_list); TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle); _set_curthread(_thread_initial); + TAILQ_INIT(&_atfork_list); + _pthread_mutex_init(&_atfork_mutex, NULL); /* Initialise the global signal action structure: */ sigfillset(&act.sa_mask); -- 2.41.0