|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _ONCE_H |
|
|
#define _ONCE_H |
|
|
|
|
|
|
|
|
#if !_GL_CONFIG_H_INCLUDED |
|
|
#error "Please include config.h first." |
|
|
#endif |
|
|
|
|
|
#include <errno.h> |
|
|
#include <stdlib.h> |
|
|
|
|
|
#if !defined c11_threads_in_use |
|
|
# if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC |
|
|
# define c11_threads_in_use() 1 |
|
|
# elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK |
|
|
# include <threads.h> |
|
|
# pragma weak thrd_exit |
|
|
# define c11_threads_in_use() (thrd_exit != NULL) |
|
|
# else |
|
|
# define c11_threads_in_use() 0 |
|
|
# endif |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS |
|
|
|
|
|
|
|
|
|
|
|
# include <threads.h> |
|
|
|
|
|
# ifdef __cplusplus |
|
|
extern "C" { |
|
|
# endif |
|
|
|
|
|
|
|
|
|
|
|
typedef once_flag gl_once_t; |
|
|
# define gl_once_define(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS once_flag NAME = ONCE_FLAG_INIT; |
|
|
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ |
|
|
(call_once (ONCE_CONTROL, INITFUNCTION), 0) |
|
|
|
|
|
# ifdef __cplusplus |
|
|
} |
|
|
# endif |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if USE_POSIX_THREADS |
|
|
|
|
|
|
|
|
|
|
|
# include <pthread.h> |
|
|
|
|
|
# ifdef __cplusplus |
|
|
extern "C" { |
|
|
# endif |
|
|
|
|
|
# if PTHREAD_IN_USE_DETECTION_HARD |
|
|
|
|
|
|
|
|
# define pthread_in_use() \ |
|
|
glthread_in_use () |
|
|
extern int glthread_in_use (void); |
|
|
|
|
|
# endif |
|
|
|
|
|
# if USE_POSIX_THREADS_WEAK |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# pragma weak pthread_mutex_init |
|
|
# pragma weak pthread_mutex_lock |
|
|
# pragma weak pthread_mutex_unlock |
|
|
# pragma weak pthread_mutex_destroy |
|
|
|
|
|
# ifndef pthread_rwlock_init |
|
|
# pragma weak pthread_rwlock_init |
|
|
# endif |
|
|
# pragma weak pthread_rwlock_rdlock |
|
|
# pragma weak pthread_rwlock_wrlock |
|
|
# pragma weak pthread_rwlock_unlock |
|
|
# pragma weak pthread_rwlock_destroy |
|
|
# pragma weak pthread_once |
|
|
# pragma weak pthread_cond_init |
|
|
# pragma weak pthread_cond_wait |
|
|
# pragma weak pthread_cond_signal |
|
|
# pragma weak pthread_cond_broadcast |
|
|
# pragma weak pthread_cond_destroy |
|
|
# pragma weak pthread_mutexattr_init |
|
|
# pragma weak pthread_mutexattr_settype |
|
|
# pragma weak pthread_mutexattr_destroy |
|
|
|
|
|
# ifndef pthread_rwlockattr_init |
|
|
# pragma weak pthread_rwlockattr_init |
|
|
# endif |
|
|
# if __GNU_LIBRARY__ > 1 |
|
|
# pragma weak pthread_rwlockattr_setkind_np |
|
|
# endif |
|
|
# pragma weak pthread_rwlockattr_destroy |
|
|
# ifndef pthread_self |
|
|
# pragma weak pthread_self |
|
|
# endif |
|
|
|
|
|
# if !PTHREAD_IN_USE_DETECTION_HARD |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# pragma weak pthread_mutexattr_gettype |
|
|
# define pthread_in_use() \ |
|
|
(pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) |
|
|
# endif |
|
|
|
|
|
# else |
|
|
|
|
|
# if !PTHREAD_IN_USE_DETECTION_HARD |
|
|
# define pthread_in_use() 1 |
|
|
# endif |
|
|
|
|
|
# endif |
|
|
|
|
|
|
|
|
|
|
|
typedef pthread_once_t gl_once_t; |
|
|
# define gl_once_define(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; |
|
|
# if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK |
|
|
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ |
|
|
(pthread_in_use () \ |
|
|
? pthread_once (ONCE_CONTROL, INITFUNCTION) \ |
|
|
: (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) |
|
|
# else |
|
|
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ |
|
|
(pthread_in_use () \ |
|
|
? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ |
|
|
: (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) |
|
|
extern int glthread_once_multithreaded (pthread_once_t *once_control, |
|
|
void (*init_function) (void)); |
|
|
# endif |
|
|
extern int glthread_once_singlethreaded (pthread_once_t *once_control); |
|
|
|
|
|
# ifdef __cplusplus |
|
|
} |
|
|
# endif |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if USE_WINDOWS_THREADS |
|
|
|
|
|
# define WIN32_LEAN_AND_MEAN |
|
|
# include <windows.h> |
|
|
|
|
|
# include "windows-once.h" |
|
|
|
|
|
# ifdef __cplusplus |
|
|
extern "C" { |
|
|
# endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef glwthread_once_t gl_once_t; |
|
|
# define gl_once_define(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; |
|
|
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ |
|
|
(glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) |
|
|
|
|
|
# ifdef __cplusplus |
|
|
} |
|
|
# endif |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef int gl_once_t; |
|
|
# define gl_once_define(STORAGECLASS, NAME) \ |
|
|
STORAGECLASS gl_once_t NAME = 0; |
|
|
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ |
|
|
(*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0) |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define gl_once(NAME, INITFUNCTION) \ |
|
|
do \ |
|
|
{ \ |
|
|
if (glthread_once (&NAME, INITFUNCTION)) \ |
|
|
abort (); \ |
|
|
} \ |
|
|
while (0) |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|