4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "thr_uberdata.h"
33 * fork handlers are run in LIFO order.
34 * The libc fork handler is expected to be the first handler installed,
35 * hence would be the last fork handler run in preparation for fork1().
36 * It is essential that this be so, for other libraries depend on libc
37 * and may grab their own locks before calling into libc. By special
38 * arrangement, the loader runs libc's init section (libc_init()) first.
42 * pthread_atfork(): installs handlers to be called during fork1().
43 * There is no POSIX API that provides for deletion of atfork handlers.
44 * Collaboration between the loader and libc ensures that atfork
45 * handlers installed by a library are deleted when that library
46 * is unloaded (see _preexec_atfork_unload() in atexit.c).
49 pthread_atfork(void (*prepare
)(void),
50 void (*parent
)(void), void (*child
)(void))
52 ulwp_t
*self
= curthread
;
53 uberdata_t
*udp
= self
->ul_uberdata
;
58 (void) mutex_lock(&udp
->atfork_lock
);
61 * Cannot call pthread_atfork() from a fork handler.
64 } else if ((atfp
= lmalloc(sizeof (atfork_t
))) == NULL
) {
67 atfp
->prepare
= prepare
;
68 atfp
->parent
= parent
;
70 if ((head
= udp
->atforklist
) == NULL
) {
71 udp
->atforklist
= atfp
;
72 atfp
->forw
= atfp
->back
= atfp
;
74 head
->back
->forw
= atfp
;
76 atfp
->back
= head
->back
;
81 (void) mutex_unlock(&udp
->atfork_lock
);
86 * _prefork_handler() is called by fork1() before it starts processing.
87 * It executes the user installed "prepare" routines in LIFO order (POSIX)
90 _prefork_handler(void)
92 uberdata_t
*udp
= curthread
->ul_uberdata
;
96 ASSERT(MUTEX_OWNED(&udp
->atfork_lock
, curthread
));
97 if ((atfork_q
= udp
->atforklist
) != NULL
) {
98 atfp
= atfork_q
= atfork_q
->back
;
102 } while ((atfp
= atfp
->back
) != atfork_q
);
107 * _postfork_parent_handler() is called by fork1() after it retuns as parent.
108 * It executes the user installed "parent" routines in FIFO order (POSIX).
111 _postfork_parent_handler(void)
113 uberdata_t
*udp
= curthread
->ul_uberdata
;
117 ASSERT(MUTEX_OWNED(&udp
->atfork_lock
, curthread
));
118 if ((atfork_q
= udp
->atforklist
) != NULL
) {
123 } while ((atfp
= atfp
->forw
) != atfork_q
);
128 * _postfork_child_handler() is called by fork1() after it returns as child.
129 * It executes the user installed "child" routines in FIFO order (POSIX).
132 _postfork_child_handler(void)
134 uberdata_t
*udp
= curthread
->ul_uberdata
;
138 ASSERT(MUTEX_OWNED(&udp
->atfork_lock
, curthread
));
139 if ((atfork_q
= udp
->atforklist
) != NULL
) {
144 } while ((atfp
= atfp
->forw
) != atfork_q
);