/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  |  | /* ========================================================================= */  |