/src/gnutls/gl/glthread/once.c
Line | Count | Source (jump to first uncovered line) |
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 | | |
34 | | static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT; |
35 | | |
36 | | int |
37 | | glthread_once_singlethreaded (pthread_once_t *once_control) |
38 | 0 | { |
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 | 0 | char *firstbyte = (char *)once_control; |
42 | 0 | if (*firstbyte == *(const char *)&fresh_once) |
43 | 0 | { |
44 | | /* First time use of once_control. Invert the first byte. */ |
45 | 0 | *firstbyte = ~ *(const char *)&fresh_once; |
46 | 0 | return 1; |
47 | 0 | } |
48 | 0 | else |
49 | 0 | return 0; |
50 | 0 | } |
51 | | |
52 | | # if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) |
53 | | |
54 | | int |
55 | | glthread_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 | | /* ========================================================================= */ |