summaryrefslogtreecommitdiffstats
path: root/gl/glthread/once.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/glthread/once.c')
-rw-r--r--gl/glthread/once.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/gl/glthread/once.c b/gl/glthread/once.c
new file mode 100644
index 00000000..53211af8
--- /dev/null
+++ b/gl/glthread/once.c
@@ -0,0 +1,80 @@
1/* Once-only initialization in multithreaded situations.
2 Copyright (C) 2005-2025 Free Software Foundation, Inc.
3
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
8
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17/* Written by Bruno Haible <bruno@clisp.org>, 2005.
18 Based on GCC's gthr-posix.h, gthr-posix95.h. */
19
20#include <config.h>
21
22#include "glthread/once.h"
23
24/* ========================================================================= */
25
26#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS
27
28#endif
29
30/* ========================================================================= */
31
32#if USE_POSIX_THREADS
33
34static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT;
35
36int
37glthread_once_singlethreaded (pthread_once_t *once_control)
38{
39 /* We don't know whether pthread_once_t is an integer type, a floating-point
40 type, a pointer type, or a structure type. */
41 char *firstbyte = (char *)once_control;
42 if (*firstbyte == *(const char *)&fresh_once)
43 {
44 /* First time use of once_control. Invert the first byte. */
45 *firstbyte = ~ *(const char *)&fresh_once;
46 return 1;
47 }
48 else
49 return 0;
50}
51
52# if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK)
53
54int
55glthread_once_multithreaded (pthread_once_t *once_control,
56 void (*init_function) (void))
57{
58 int err = pthread_once (once_control, init_function);
59 if (err == ENOSYS)
60 {
61 /* This happens on FreeBSD 11: The pthread_once function in libc returns
62 ENOSYS. */
63 if (glthread_once_singlethreaded (once_control))
64 init_function ();
65 return 0;
66 }
67 return err;
68}
69
70# endif
71
72#endif
73
74/* ========================================================================= */
75
76#if USE_WINDOWS_THREADS
77
78#endif
79
80/* ========================================================================= */