FreeBSD Bugzilla – Attachment 8296 Details for
Bug 17437
pthread_atfork() missing from libc_r
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 6.06 KB, created by
mikko
on 2000-03-17 18:30:02 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
mikko
Created:
2000-03-17 18:30:02 UTC
Size:
6.06 KB
patch
obsolete
>--- lib/libc_r/uthread/Makefile.inc.org Thu Mar 16 22:31:06 2000 >+++ lib/libc_r/uthread/Makefile.inc Thu Mar 16 22:31:42 2000 >@@ -6,6 +6,7 @@ > SRCS+= \ > uthread_accept.c \ > uthread_aio_suspend.c \ >+ uthread_atfork.c \ > uthread_attr_destroy.c \ > uthread_attr_init.c \ > uthread_attr_getdetachstate.c \ >--- lib/libc_r/man/pthread_atfork.3.orig Fri Mar 17 19:01:53 2000 >+++ lib/libc_r/man/pthread_atfork.3 Fri Mar 17 19:01:47 2000 >@@ -0,0 +1,73 @@ >+.\" >+.\" "THE BEER-WARE LICENSE" (Revision 42m): >+.\" <mikko@dynas.se> wrote this file. As long as you retain this notice you >+.\" can do whatever you want with this stuff. If we meet some day, and you think >+.\" this stuff is worth it, you can buy me a beer in return. Mikko Työläjärvi >+.\" >+.\" $FreeBSD$ >+.\" >+.Dd March 16, 2000 >+.Dt PTHREAD_ATFORK 3 >+.Os BSD 4 >+.Sh NAME >+.Nm pthread_atfork >+.Nd register fork handlers >+.Sh SYNOPSIS >+.Fd #include <pthread.h> >+.Ft int >+.Fn pthread_atfork "void (*prepare)(void)" "void (*parent)(void)" "void (*child)(void)" >+.Sh DESCRIPTION >+The >+.Fn pthread_atfork >+function registers fork handlers to be called before and after >+.Fn fork . >+Handlers are run in the context of the thread that calls >+.Fn fork . >+.Pp >+The >+.Fa prepare >+handlers are invoked before fork processing. The >+.Fa parent >+and >+.Fa child >+handlers are invoked after fork processing, in the parent and child >+processes respectively. >+Handlers will be called in the parent process even when the >+.Fn fork >+operation fails. >+.Pp >+Any number of handlers can be registered by >+.Fn pthread_atfork . >+Function pointers that are NULL will be ignored. >+The >+.Fa Parent >+and >+.Fa child >+handlers are called in the order that they were registered. The >+.Fn prepare >+handlers are called in the reverse order. >+.Pp >+.Sh RETURN VALUES >+If successful, the >+.Fn pthread_atfork >+function will return zero. >+Otherwise an error number will be returned to >+indicate the error. >+.Sh ERRORS >+.Fn pthread_atfork >+will fail if: >+.Bl -tag -width Er >+.It Bq Er ENOMEM >+The process cannot allocate enough memory to register another set of >+handlers. >+.El >+.Pp >+.Sh SEE ALSO >+.Xr fork 2 , >+.Xr atexit 3 >+.Sh STANDARDS >+.Fn pthread_atfork >+conforms to ISO/IEC 9945-1 ANSI/IEEE >+.Pq Dq Tn POSIX >+.\" XXX: Dunno -- someone will have to check the exact details: >+Std 1003.1 Second Edition 1996-07-12. >--- lib/libc_r/man/Makefile.inc.org Fri Mar 17 18:42:54 2000 >+++ lib/libc_r/man/Makefile.inc Fri Mar 17 18:42:31 2000 >@@ -4,7 +4,8 @@ > > .PATH: ${.CURDIR}/man > >-MAN3+= pthread_cancel.3 \ >+MAN3+= pthread_atfork.3 \ >+ pthread_cancel.3 \ > pthread_cleanup_pop.3 \ > pthread_cleanup_push.3 \ > pthread_cond_broadcast.3 \ >--- include/pthread.h.org Thu Mar 16 22:29:54 2000 >+++ include/pthread.h Thu Mar 16 22:37:37 2000 >@@ -303,6 +303,9 @@ > > int pthread_attr_setfloatstate __P((pthread_attr_t *, int)); > int pthread_attr_getfloatstate __P((pthread_attr_t *, int *)); >+ >+int pthread_atfork __P((void (*prepare)(void), >+ void (*parent)(void), void (*child)(void))); > __END_DECLS > > #endif >--- lib/libc_r/uthread/pthread_private.h.org Thu Mar 16 22:30:22 2000 >+++ lib/libc_r/uthread/pthread_private.h Fri Mar 17 16:26:21 2000 >@@ -999,6 +999,16 @@ > #define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type) > #endif > >+/* Atfork handlers */ >+#define ATFORK_PREPARE 0 >+#define ATFORK_PARENT 1 >+#define ATFORK_CHILD 2 >+ >+typedef struct atfork_data { >+ struct atfork_data *next, *prev; >+ void (*funcs[3])(void); >+} atfork_data; >+ > /* > * Function prototype definitions. > */ >@@ -1060,6 +1070,7 @@ > void _thread_enter_cancellation_point(void); > void _thread_leave_cancellation_point(void); > void _thread_cancellation_point(void); >+atfork_data *_thread_atfork_list(void); > > /* #include <signal.h> */ > int _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *); >--- lib/libc_r/uthread/uthread_atfork.c.org Fri Mar 17 18:37:07 2000 >+++ lib/libc_r/uthread/uthread_atfork.c Fri Mar 17 18:27:19 2000 >@@ -0,0 +1,56 @@ >+/* >+ * "THE BEER-WARE LICENSE" (Revision 42m): >+ * <mikko@dynas.se> wrote this file. As long as you retain this notice you >+ * can do whatever you want with this stuff. If we meet some day, and you think >+ * this stuff is worth it, you can buy me a beer in return. Mikko Työläjärvi >+ * >+ * $FreeBSD$ >+ */ >+ >+#include <errno.h> >+#include <stdlib.h> >+#ifdef _THREAD_SAFE >+#include <pthread.h> >+#include "pthread_private.h" >+ >+static atfork_data *atfork_list = NULL; >+static spinlock_t atfork_lock = _SPINLOCK_INITIALIZER; >+ >+int >+pthread_atfork(void (*prepare)(void), >+ void (*parent)(void), >+ void (*child)(void)) >+{ >+ atfork_data *ap; >+ >+ if (prepare == NULL && parent == NULL && child == NULL) >+ return 0; >+ >+ if ((ap = malloc(sizeof(atfork_data))) == NULL) >+ return ENOMEM; >+ >+ ap->funcs[ATFORK_PREPARE] = prepare; >+ ap->funcs[ATFORK_PARENT] = parent; >+ ap->funcs[ATFORK_CHILD] = child; >+ >+ _SPINLOCK(&atfork_lock); >+ if ((ap->next = atfork_list) != NULL) >+ atfork_list->prev = ap; >+ atfork_list = ap; >+ _SPINUNLOCK(&atfork_lock); >+ >+ return 0; >+} >+ >+atfork_data * >+_thread_atfork_list(void) >+{ >+ atfork_data *ap; >+ >+ _SPINLOCK(&atfork_lock); >+ ap = atfork_list; >+ _SPINUNLOCK(&atfork_lock); >+ >+ return ap; >+} >+#endif >--- lib/libc_r/uthread/uthread_fork.c.org Fri Mar 17 18:12:22 2000 >+++ lib/libc_r/uthread/uthread_fork.c Fri Mar 17 18:10:23 2000 >@@ -47,6 +47,16 @@ > pid_t ret; > pthread_t pthread; > pthread_t pthread_save; >+ atfork_data *ap, *alist; >+ >+ /* Run any registered "prepare" callbacks: */ >+ alist = _thread_atfork_list(); >+ for (ap = alist; ap != NULL; ap = ap->next) { >+ if (ap->funcs[ATFORK_PREPARE] != NULL) >+ ap->funcs[ATFORK_PREPARE](); >+ if (ap->next == NULL) >+ break; >+ } > > /* > * Defer signals to protect the scheduling queues from access >@@ -216,6 +226,15 @@ > * Undefer and handle pending signals, yielding if necessary: > */ > _thread_kern_sig_undefer(); >+ >+ /* >+ * Run any parent/child callbacks matching the "prepare" callbacks >+ * from function entry, in reverse order: >+ */ >+ i = ret ? ATFORK_PARENT : ATFORK_CHILD; >+ for (; ap != NULL; ap = (ap != alist) ? ap->prev : NULL) >+ if (ap->funcs[i] != NULL) >+ ap->funcs[i](); > > /* Return the process ID: */ > return (ret);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 17437
: 8296