call_once, being implemented on top of pthread_once in Cygwin, is affected by the same bug, and needs a workaround as well.
2024-05-30 Bruno Haible <br...@clisp.org> call_once: Work around Cygwin 3.5.3 bug. * m4/call_once.m4 (gl_FUNC_CALL_ONCE): Require AC_CANONICAL_HOST. On Cygwin, set REPLACE_CALL_ONCE to 1. * lib/call_once.c (call_once): On Cygwin, use a cast, to avoid a compiler warning. * modules/call_once (Depends-on): Add pthread-once. * doc/posix-functions/call_once.texi: Mention the Cygwin bug. diff --git a/doc/posix-functions/call_once.texi b/doc/posix-functions/call_once.texi index 6ae72b0d43..bf0f20ff55 100644 --- a/doc/posix-functions/call_once.texi +++ b/doc/posix-functions/call_once.texi @@ -22,6 +22,9 @@ Portability problems not fixed by Gnulib: @itemize @item +This function makes applications hang forever on some platforms: +Cygwin 3.5.3. +@item This function does not work on some platforms: @c https://dev.haiku-os.org/ticket/18348 Haiku. diff --git a/lib/call_once.c b/lib/call_once.c index 9ef517bdd7..54a864deda 100644 --- a/lib/call_once.c +++ b/lib/call_once.c @@ -53,7 +53,13 @@ call_once (once_flag *flagp, void (*func) (void)) void call_once (once_flag *flagp, void (*func) (void)) { +# if defined __CYGWIN__ + /* Verify that once_flag and pthread_once_t are of the same size. */ + struct _ { int v [sizeof (once_flag) == sizeof (pthread_once_t) ? 1 : -1]; }; + pthread_once ((pthread_once_t *) flagp, func); +# else pthread_once (flagp, func); +# endif } #endif diff --git a/m4/call_once.m4 b/m4/call_once.m4 index 0272485a91..b7919e275b 100644 --- a/m4/call_once.m4 +++ b/m4/call_once.m4 @@ -1,5 +1,5 @@ # call_once.m4 -# serial 1 +# serial 2 dnl Copyright (C) 2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,8 +8,23 @@ AC_DEFUN([gl_FUNC_CALL_ONCE], [ AC_REQUIRE([gl_THREADS_H]) + AC_REQUIRE([AC_CANONICAL_HOST]) gl_CHECK_FUNCS_ANDROID([call_once], [[#include <threads.h>]]) case "$gl_cv_onwards_func_call_once" in + yes) + dnl Work around Cygwin 3.5.3 bug. + AC_CACHE_CHECK([whether call_once works], + [gl_cv_func_call_once_works], + [case "$host_os" in + cygwin*) gl_cv_func_call_once_works="guessing no" ;; + *) gl_cv_func_call_once_works="yes" ;; + esac + ]) + case "$gl_cv_func_call_once_works" in + *yes) ;; + *) REPLACE_CALL_ONCE=1 ;; + esac + ;; future*) REPLACE_CALL_ONCE=1 ;; diff --git a/modules/call_once b/modules/call_once index c48847a54b..1fa4d47744 100644 --- a/modules/call_once +++ b/modules/call_once @@ -7,6 +7,7 @@ m4/call_once.m4 Depends-on: threads-h +pthread-once windows-once configure.ac: