diff options
Diffstat (limited to 'lib/glthread/once.c')
| -rw-r--r-- | lib/glthread/once.c | 80 | 
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/glthread/once.c b/lib/glthread/once.c new file mode 100644 index 00000000..869ba3ba --- /dev/null +++ b/lib/glthread/once.c @@ -0,0 +1,80 @@ +/* Once-only initialization in multithreaded situations. +   Copyright (C) 2005-2024 Free Software Foundation, Inc. + +   This file is free software: you can redistribute it and/or modify +   it under the terms of the GNU Lesser General Public License as +   published by the Free Software Foundation; either version 2.1 of the +   License, or (at your option) any later version. + +   This file is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public License +   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2005. +   Based on GCC's gthr-posix.h, gthr-posix95.h.  */ + +#include <config.h> + +#include "glthread/once.h" + +/* ========================================================================= */ + +#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS + +#endif + +/* ========================================================================= */ + +#if USE_POSIX_THREADS + +static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT; + +int +glthread_once_singlethreaded (pthread_once_t *once_control) +{ +  /* We don't know whether pthread_once_t is an integer type, a floating-point +     type, a pointer type, or a structure type.  */ +  char *firstbyte = (char *)once_control; +  if (*firstbyte == *(const char *)&fresh_once) +    { +      /* First time use of once_control.  Invert the first byte.  */ +      *firstbyte = ~ *(const char *)&fresh_once; +      return 1; +    } +  else +    return 0; +} + +# if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) + +int +glthread_once_multithreaded (pthread_once_t *once_control, +                             void (*init_function) (void)) +{ +  int err = pthread_once (once_control, init_function); +  if (err == ENOSYS) +    { +      /* This happens on FreeBSD 11: The pthread_once function in libc returns +         ENOSYS.  */ +      if (glthread_once_singlethreaded (once_control)) +        init_function (); +      return 0; +    } +  return err; +} + +# endif + +#endif + +/* ========================================================================= */ + +#if USE_WINDOWS_THREADS + +#endif + +/* ========================================================================= */  | 
