From 62b1ec6e3667b903b262c213211453eadd3f1f93 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sun, 30 Oct 2005 03:37:35 +0000 Subject: Add pthread_atfork(3) From FreeBSD 'looks ok' fgsch@ miod@ man page reviewed by jmc@ --- lib/libpthread/uthread/Makefile.inc | 3 +- lib/libpthread/uthread/pthread_private.h | 12 ++++++- lib/libpthread/uthread/uthread_atfork.c | 58 ++++++++++++++++++++++++++++++++ lib/libpthread/uthread/uthread_fork.c | 24 +++++++++++-- lib/libpthread/uthread/uthread_init.c | 4 ++- 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 lib/libpthread/uthread/uthread_atfork.c (limited to 'lib/libpthread/uthread') diff --git a/lib/libpthread/uthread/Makefile.inc b/lib/libpthread/uthread/Makefile.inc index 02c07c5481b..6ef4e88c344 100644 --- a/lib/libpthread/uthread/Makefile.inc +++ b/lib/libpthread/uthread/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.18 2004/02/22 23:59:26 brad Exp $ +# $OpenBSD: Makefile.inc,v 1.19 2005/10/30 03:37:34 brad Exp $ # $FreeBSD: Makefile.inc,v 1.19 1999/08/28 00:03:19 peter Exp $ # uthread sources @@ -8,6 +8,7 @@ CFLAGS += -I${SRCDIR}/arch/${MACHINE_ARCH} SRCS+= \ uthread_accept.c \ + uthread_atfork.c \ uthread_attr_destroy.c \ uthread_attr_init.c \ uthread_attr_getdetachstate.c \ diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h index aef55382c95..bfb038aa671 100644 --- a/lib/libpthread/uthread/pthread_private.h +++ b/lib/libpthread/uthread/pthread_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pthread_private.h,v 1.53 2004/06/07 21:11:23 marc Exp $ */ +/* $OpenBSD: pthread_private.h,v 1.54 2005/10/30 03:37:34 brad Exp $ */ /* * Copyright (c) 1995-1998 John Birrell . * All rights reserved. @@ -345,6 +345,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; @@ -901,6 +908,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/libpthread/uthread/uthread_atfork.c b/lib/libpthread/uthread/uthread_atfork.c new file mode 100644 index 00000000000..10e6f6be25b --- /dev/null +++ b/lib/libpthread/uthread/uthread_atfork.c @@ -0,0 +1,58 @@ +/* $OpenBSD: uthread_atfork.c,v 1.3 2005/10/30 03:37:34 brad Exp $ */ + +/* + * 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: /repoman/r/ncvs/src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2004/12/10 03:36:45 grog Exp $ + */ + +#include +#include +#ifdef _THREAD_SAFE +#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); +} +#endif diff --git a/lib/libpthread/uthread/uthread_fork.c b/lib/libpthread/uthread/uthread_fork.c index 02f7656859b..09a3279392a 100644 --- a/lib/libpthread/uthread/uthread_fork.c +++ b/lib/libpthread/uthread/uthread_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_fork.c,v 1.11 2003/08/06 21:08:05 millert Exp $ */ +/* $OpenBSD: uthread_fork.c,v 1.12 2005/10/30 03:37:34 brad Exp $ */ /* * Copyright (c) 1995-1998 John Birrell * All rights reserved. @@ -45,6 +45,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 = _thread_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: */ _thread_sys_close(_thread_kern_pipe[0]); @@ -178,6 +192,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/libpthread/uthread/uthread_init.c b/lib/libpthread/uthread/uthread_init.c index 531753880e6..69a70e5a22a 100644 --- a/lib/libpthread/uthread/uthread_init.c +++ b/lib/libpthread/uthread/uthread_init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_init.c,v 1.32 2004/06/07 21:11:23 marc Exp $ */ +/* $OpenBSD: uthread_init.c,v 1.33 2005/10/30 03:37:34 brad Exp $ */ /* * Copyright (c) 1995-1998 John Birrell * All rights reserved. @@ -289,6 +289,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); -- cgit v1.2.3