Remove unused localedata/th_TH.in
[glibc.git] / sysdeps / pthread / tst-atfork3.c
blob5930cdc2f90ab821ca53e9dfa7da2e803af97de5
1 /* Check if pthread_atfork handler can call dlclose (BZ#24595).
2 Copyright (C) 2022-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <stdio.h>
20 #include <pthread.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <stdbool.h>
25 #include <support/check.h>
26 #include <support/xthread.h>
27 #include <support/capture_subprocess.h>
28 #include <support/xdlfcn.h>
30 /* Check if pthread_atfork handlers do not deadlock when calling a function
31 that might alter the internal fork handle list, such as dlclose.
33 The test registers a callback set with pthread_atfork(), dlopen() a shared
34 library (nptl/tst-atfork3mod.c), calls an exported symbol from the library
35 (which in turn also registers atfork handlers), and calls fork to trigger
36 the callbacks. */
38 static void *handler;
39 static bool run_dlclose_prepare;
40 static bool run_dlclose_parent;
41 static bool run_dlclose_child;
43 static void
44 prepare (void)
46 if (run_dlclose_prepare)
47 xdlclose (handler);
50 static void
51 parent (void)
53 if (run_dlclose_parent)
54 xdlclose (handler);
57 static void
58 child (void)
60 if (run_dlclose_child)
61 xdlclose (handler);
64 static void
65 proc_func (void *closure)
69 static void
70 do_test_generic (bool dlclose_prepare, bool dlclose_parent, bool dlclose_child)
72 run_dlclose_prepare = dlclose_prepare;
73 run_dlclose_parent = dlclose_parent;
74 run_dlclose_child = dlclose_child;
76 handler = xdlopen ("tst-atfork3mod.so", RTLD_NOW);
78 int (*atfork3mod_func)(void);
79 atfork3mod_func = xdlsym (handler, "atfork3mod_func");
81 atfork3mod_func ();
83 struct support_capture_subprocess proc
84 = support_capture_subprocess (proc_func, NULL);
85 support_capture_subprocess_check (&proc, "tst-atfork3", 0, sc_allow_none);
87 handler = atfork3mod_func = NULL;
89 support_capture_subprocess_free (&proc);
92 static void *
93 thread_func (void *closure)
95 return NULL;
98 static int
99 do_test (void)
102 /* Make the process acts as multithread. */
103 pthread_attr_t attr;
104 xpthread_attr_init (&attr);
105 xpthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
106 xpthread_create (&attr, thread_func, NULL);
109 TEST_COMPARE (pthread_atfork (prepare, parent, child), 0);
111 do_test_generic (true /* prepare */, false /* parent */, false /* child */);
112 do_test_generic (false /* prepare */, true /* parent */, false /* child */);
113 do_test_generic (false /* prepare */, false /* parent */, true /* child */);
115 return 0;
118 #include <support/test-driver.c>