Add pthread_atfork() implementation to libc_r. libthread_xu has it already,
authorHasso Tepper <hasso@dragonflybsd.org>
Sun, 25 May 2008 21:34:49 +0000 (21:34 +0000)
committerHasso Tepper <hasso@dragonflybsd.org>
Sun, 25 May 2008 21:34:49 +0000 (21:34 +0000)
but it was unusable due to missing code in libc_r.

Obtained-from: FreeBSD

lib/libc/gen/pthread_fake.c
lib/libc_r/uthread/Makefile.inc
lib/libc_r/uthread/pthread_private.h
lib/libc_r/uthread/uthread_atfork.c [new file with mode: 0644]
lib/libc_r/uthread/uthread_fork.c
lib/libc_r/uthread/uthread_init.c

index dd2d989..7b28929 100644 (file)
@@ -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);
index 59f2873..1c79664 100644 (file)
@@ -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 \
index b4ef115..ceae8ba 100644 (file)
@@ -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 (file)
index 0000000..de987e7
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003 Daniel Eischen <deischen at freebsd.org>
+ * 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 <errno.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/queue.h>
+#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);
index b933543..b432dc6 100644 (file)
@@ -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 <errno.h>
 #include <string.h>
@@ -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);
        }
 
        /*
index 517bae6..25d1cb0 100644 (file)
@@ -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);