In ISO C 23,
- the type 'once_flag',
- the macro ONCE_FLAG_INIT,
- the declaration of function 'call_once'
are all available from <stdlib.h>, not only from <threads.h>.
1) This makes it clear that often call_once is needed in an application
without also needing mutexes. For this reason, I'm moving the 'call_once'
function definition out of the 'mtx' module, into a module of its own.
2) The requirement to have 'once_flag' defined in <stdlib.h> would mean
that Gnulib's stdlib.h replacement would have
- to include <pthread.h> on Unix platforms, and
- to include <windows.h> on native Windows.
Each of the two includes would cause a lot of trouble to users:
- for <pthread.h>, by having many more cases of header file recursion
(we had that often, and the workarounds were always ad-hoc),
- for <windows.h>, by defining lots of identifiers in the namespace.
This is not worth the trouble, given that the workaround — include
<threads.h> instead of <stdlib.h> — is in the realm of ISO C and
very simple. I'm therefore not implementing ISO C 23 compatibility
on this point. We can revisit it in 10 years or so; then hopefully
some platforms will have restructured their header files and will
define 'once_flag' in <stdlib.h>.
2023-03-25 Bruno Haible <[email protected]>
stdlib: ISO C 23: Document issue with once_flag and call_once.
* doc/posix-headers/stdlib.texi: Document issue and workaround.
2023-03-25 Bruno Haible <[email protected]>
call_once: New module, separate from mtx.
* lib/threads.in.h (call_once): Declare as part of module 'call_once',
not module 'mtx'.
* lib/call_once.c: New file, extracted from lib/mtx.c.
* lib/mtx.c (call_once): Remove function.
* m4/threads_h.m4 (gl_THREADS_H_REQUIRE_DEFAULTS): Inititalize
GNULIB_CALL_ONCE.
* modules/threads-h (Makefile.am): Substitute GNULIB_CALL_ONCE.
* modules/call_once: New file, based on modules/mtx.
* modules/threads (Depends-on): Add call_once.
* tests/test-threads-c++.cc: Update accordingly.
* modules/call_once-tests: New file, based on modules/mtx-tests.
* modules/mtx-tests (Files): Remove tests/test-call_once.c.
(Makefile.am): Don't compile test-call_once.
* doc/posix-functions/call_once.texi: Document that the relevant module
is now 'call_once'.
* NEWS: Mention the change.
>From 53370c23642eb6256dafd7b6abca8cc93581b7c2 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sat, 25 Mar 2023 20:54:29 +0100
Subject: [PATCH 1/2] call_once: New module, separate from mtx.
* lib/threads.in.h (call_once): Declare as part of module 'call_once',
not module 'mtx'.
* lib/call_once.c: New file, extracted from lib/mtx.c.
* lib/mtx.c (call_once): Remove function.
* m4/threads_h.m4 (gl_THREADS_H_REQUIRE_DEFAULTS): Inititalize
GNULIB_CALL_ONCE.
* modules/threads-h (Makefile.am): Substitute GNULIB_CALL_ONCE.
* modules/call_once: New file, based on modules/mtx.
* modules/threads (Depends-on): Add call_once.
* tests/test-threads-c++.cc: Update accordingly.
* modules/call_once-tests: New file, based on modules/mtx-tests.
* modules/mtx-tests (Files): Remove tests/test-call_once.c.
(Makefile.am): Don't compile test-call_once.
* doc/posix-functions/call_once.texi: Document that the relevant module
is now 'call_once'.
* NEWS: Mention the change.
---
ChangeLog | 20 ++++++++++
NEWS | 4 ++
doc/posix-functions/call_once.texi | 2 +-
lib/call_once.c | 59 ++++++++++++++++++++++++++++++
lib/mtx.c | 12 ------
lib/threads.in.h | 2 +-
m4/threads_h.m4 | 3 +-
modules/call_once | 31 ++++++++++++++++
modules/call_once-tests | 12 ++++++
modules/mtx-tests | 6 +--
modules/threads | 1 +
modules/threads-h | 1 +
tests/test-threads-c++.cc | 3 ++
13 files changed, 137 insertions(+), 19 deletions(-)
create mode 100644 lib/call_once.c
create mode 100644 modules/call_once
create mode 100644 modules/call_once-tests
diff --git a/ChangeLog b/ChangeLog
index 9dd1b50086..07b96d5860 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2023-03-25 Bruno Haible <[email protected]>
+
+ call_once: New module, separate from mtx.
+ * lib/threads.in.h (call_once): Declare as part of module 'call_once',
+ not module 'mtx'.
+ * lib/call_once.c: New file, extracted from lib/mtx.c.
+ * lib/mtx.c (call_once): Remove function.
+ * m4/threads_h.m4 (gl_THREADS_H_REQUIRE_DEFAULTS): Inititalize
+ GNULIB_CALL_ONCE.
+ * modules/threads-h (Makefile.am): Substitute GNULIB_CALL_ONCE.
+ * modules/call_once: New file, based on modules/mtx.
+ * modules/threads (Depends-on): Add call_once.
+ * tests/test-threads-c++.cc: Update accordingly.
+ * modules/call_once-tests: New file, based on modules/mtx-tests.
+ * modules/mtx-tests (Files): Remove tests/test-call_once.c.
+ (Makefile.am): Don't compile test-call_once.
+ * doc/posix-functions/call_once.texi: Document that the relevant module
+ is now 'call_once'.
+ * NEWS: Mention the change.
+
2023-03-25 Bruno Haible <[email protected]>
stdio: ISO C 23: Define _PRINTF_NAN_LEN_MAX.
diff --git a/NEWS b/NEWS
index 7863514118..fcfaf4906b 100644
--- a/NEWS
+++ b/NEWS
@@ -74,6 +74,10 @@ User visible incompatible changes
Date Modules Changes
+2023-03-25 mtx This module no longer provides the function
+ call_once. To get this function, use the new
+ separate module 'call_once'.
+
2023-03-08 time This module is renamed to 'time-h'.
The new 'time' module now also works around an
inconsistency in glibc 2.31+ on Linux.
diff --git a/doc/posix-functions/call_once.texi b/doc/posix-functions/call_once.texi
index ee798db963..e7c6f07542 100644
--- a/doc/posix-functions/call_once.texi
+++ b/doc/posix-functions/call_once.texi
@@ -10,7 +10,7 @@
@url{https://www.gnu.org/software/libc/manual/html_node/Call-Once.html}.
@end ifnotinfo
-Gnulib module: mtx
+Gnulib module: call_once
Portability problems fixed by Gnulib:
@itemize
diff --git a/lib/call_once.c b/lib/call_once.c
new file mode 100644
index 0000000000..d11d9506fb
--- /dev/null
+++ b/lib/call_once.c
@@ -0,0 +1,59 @@
+/* ISO C 11 once-only initialization.
+ Copyright (C) 2005-2023 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 <[email protected]>, 2005, 2019.
+ Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h. */
+
+#include <config.h>
+
+#include <threads.h>
+
+#include <errno.h>
+
+#if defined _WIN32 && ! defined __CYGWIN__
+/* Use Windows threads. */
+
+# define WIN32_LEAN_AND_MEAN /* avoid including junk */
+# include <windows.h>
+
+# include <stdlib.h>
+
+#else
+/* Use POSIX threads. */
+
+# include <pthread.h>
+
+#endif
+
+#if defined _WIN32 && ! defined __CYGWIN__
+/* Use Windows threads. */
+
+void
+call_once (once_flag *flagp, void (*func) (void))
+{
+ glwthread_once (flagp, func);
+}
+
+#else
+/* Use POSIX threads. */
+
+void
+call_once (once_flag *flagp, void (*func) (void))
+{
+ pthread_once (flagp, func);
+}
+
+#endif
diff --git a/lib/mtx.c b/lib/mtx.c
index fe15b69494..9292773cf4 100644
--- a/lib/mtx.c
+++ b/lib/mtx.c
@@ -187,12 +187,6 @@ mtx_destroy (mtx_t *mutex)
}
}
-void
-call_once (once_flag *flagp, void (*func) (void))
-{
- glwthread_once (flagp, func);
-}
-
#else
/* Use POSIX threads. */
@@ -279,10 +273,4 @@ mtx_destroy (mtx_t *mutex)
pthread_mutex_destroy (mutex);
}
-void
-call_once (once_flag *flagp, void (*func) (void))
-{
- pthread_once (flagp, func);
-}
-
#endif
diff --git a/lib/threads.in.h b/lib/threads.in.h
index e34c39de3f..2bc0f23b32 100644
--- a/lib/threads.in.h
+++ b/lib/threads.in.h
@@ -459,7 +459,7 @@ typedef pthread_once_t once_flag;
#endif
-#if @GNULIB_MTX@
+#if @GNULIB_CALL_ONCE@
# if !@HAVE_THREADS_H@
_GL_FUNCDECL_SYS (call_once, void, (once_flag *, void (*) (void))
_GL_ARG_NONNULL ((1, 2)));
diff --git a/m4/threads_h.m4 b/m4/threads_h.m4
index 77fe20d279..851490c123 100644
--- a/m4/threads_h.m4
+++ b/m4/threads_h.m4
@@ -1,4 +1,4 @@
-# threads_h.m4 serial 10
+# threads_h.m4 serial 11
dnl Copyright (C) 2019-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -156,6 +156,7 @@ AC_DEFUN([gl_THREADS_MODULE_INDICATOR]
AC_DEFUN([gl_THREADS_H_REQUIRE_DEFAULTS],
[
m4_defun(GL_MODULE_INDICATOR_PREFIX[_THREADS_H_MODULE_INDICATOR_DEFAULTS], [
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALL_ONCE])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CND])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MTX])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_THRD])
diff --git a/modules/call_once b/modules/call_once
new file mode 100644
index 0000000000..3efc3f3736
--- /dev/null
+++ b/modules/call_once
@@ -0,0 +1,31 @@
+Description:
+call_once() function: ISO C 11 once-only initialization.
+
+Files:
+lib/call_once.c
+
+Depends-on:
+threads-h
+windows-once
+
+configure.ac:
+AC_REQUIRE([gl_THREADS_H])
+gl_CONDITIONAL([GL_COND_OBJ_CALL_ONCE], [test $HAVE_THREADS_H = 0])
+gl_THREADS_MODULE_INDICATOR([call_once])
+
+Makefile.am:
+if GL_COND_OBJ_CALL_ONCE
+lib_SOURCES += call_once.c
+endif
+
+Include:
+<threads.h>
+
+Link:
+$(LIBSTDTHREAD)
+
+License:
+LGPLv2+
+
+Maintainer:
+all
diff --git a/modules/call_once-tests b/modules/call_once-tests
new file mode 100644
index 0000000000..70bae25eb3
--- /dev/null
+++ b/modules/call_once-tests
@@ -0,0 +1,12 @@
+Files:
+tests/test-call_once.c
+tests/macros.h
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-call_once
+check_PROGRAMS += test-call_once
+test_call_once_LDADD = $(LDADD) @LIBSTDTHREAD@
diff --git a/modules/mtx-tests b/modules/mtx-tests
index 52310625a5..4a021d22fa 100644
--- a/modules/mtx-tests
+++ b/modules/mtx-tests
@@ -1,6 +1,5 @@
Files:
tests/test-mtx.c
-tests/test-call_once.c
tests/atomic-int-isoc.h
tests/macros.h
@@ -14,7 +13,6 @@ AC_CHECK_HEADERS_ONCE([semaphore.h])
AC_CHECK_DECLS_ONCE([alarm])
Makefile.am:
-TESTS += test-mtx test-call_once
-check_PROGRAMS += test-mtx test-call_once
+TESTS += test-mtx
+check_PROGRAMS += test-mtx
test_mtx_LDADD = $(LDADD) @LIBSTDTHREAD@ @LIBTHREAD@
-test_call_once_LDADD = $(LDADD) @LIBSTDTHREAD@
diff --git a/modules/threads b/modules/threads
index 18391c1c2d..c5bed1c328 100644
--- a/modules/threads
+++ b/modules/threads
@@ -6,6 +6,7 @@ Files:
Depends-on:
threads-h
thrd
+call_once
mtx
cnd
tss
diff --git a/modules/threads-h b/modules/threads-h
index 50a60dfdab..1a2b83a354 100644
--- a/modules/threads-h
+++ b/modules/threads-h
@@ -50,6 +50,7 @@ threads.h: threads.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(_NORETURN_H
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_AS_FIRST_DIRECTIVE_THREADS_H''@|$(NEXT_AS_FIRST_DIRECTIVE_THREADS_H)|g' \
-e 's|@''NEXT_THREADS_H''@|$(NEXT_THREADS_H)|g' \
+ -e 's/@''GNULIB_CALL_ONCE''@/$(GNULIB_CALL_ONCE)/g' \
-e 's/@''GNULIB_CND''@/$(GNULIB_CND)/g' \
-e 's/@''GNULIB_MTX''@/$(GNULIB_MTX)/g' \
-e 's/@''GNULIB_THRD''@/$(GNULIB_THRD)/g' \
diff --git a/tests/test-threads-c++.cc b/tests/test-threads-c++.cc
index 7c3bcb80b1..d82b526458 100644
--- a/tests/test-threads-c++.cc
+++ b/tests/test-threads-c++.cc
@@ -45,6 +45,9 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::mtx_timedlock, int,
(mtx_t *, const struct timespec *));
SIGNATURE_CHECK (GNULIB_NAMESPACE::mtx_unlock, int, (mtx_t *));
SIGNATURE_CHECK (GNULIB_NAMESPACE::mtx_destroy, void, (mtx_t *));
+#endif
+
+#if GNULIB_TEST_CALL_ONCE
SIGNATURE_CHECK (GNULIB_NAMESPACE::call_once, void,
(once_flag *, void (*) (void)));
#endif
--
2.34.1
>From 55a1207abc196655b9ef7c34b3cb7d736e6e7fe7 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sat, 25 Mar 2023 21:48:31 +0100
Subject: [PATCH 2/2] stdlib: ISO C 23: Document issue with once_flag and
call_once.
* doc/posix-headers/stdlib.texi: Document issue and workaround.
---
ChangeLog | 5 +++++
doc/posix-headers/stdlib.texi | 6 ++++++
2 files changed, 11 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 07b96d5860..a0de338759 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2023-03-25 Bruno Haible <[email protected]>
+
+ stdlib: ISO C 23: Document issue with once_flag and call_once.
+ * doc/posix-headers/stdlib.texi: Document issue and workaround.
+
2023-03-25 Bruno Haible <[email protected]>
call_once: New module, separate from mtx.
diff --git a/doc/posix-headers/stdlib.texi b/doc/posix-headers/stdlib.texi
index e7145b7dcc..612e794068 100644
--- a/doc/posix-headers/stdlib.texi
+++ b/doc/posix-headers/stdlib.texi
@@ -29,6 +29,12 @@
Portability problems not fixed by Gnulib:
@itemize
@item
+The definition of the type @code{once_flag}, of the macro
+@code{ONCE_FLAG_INIT}, and the declaration of the function
+@code{call_once}, that are required by ISO C 23, are not provided.
+To get them, import Gnulib module @code{call_once} and include
+@code{<threads.h>} rather than @code{<stdlib.h>}.
+@item
System status macros such as @code{WEXITSTATUS} require an lvalue
argument on some platforms.
macOS 11.1.
--
2.34.1