+2023-11-10 Bruno Haible <bruno@clisp.org>
+
+ random: Fix multithread-safety bug.
+ * m4/random.m4 (gl_FUNC_RANDOM): Override on macOS, FreeBSD, Solaris,
+ Cygwin, Haiku.
+ * lib/random.c: Include glthread/lock.h.
+ (__libc_lock_define_initialized, __libc_lock_lock, __libc_lock_unlock):
+ Define to do real locking.
+ * modules/random (Depends-on): Add lock.
+ * doc/posix-functions/random.texi: Mention the multithread-safety
+ problem.
+
2023-11-08 Bruno Haible <bruno@clisp.org>
pthread-rwlock: Port to Mac OS X 10.4.
This function is only defined as an inline function on some platforms:
Android 4.4.
@item
-
+This function is not multithread-safe on some platforms:
+macOS 12.5, FreeBSD 13.2, Solaris 11.4, Cygwin 3.4.6, Haiku.
@end itemize
Portability problems not fixed by Gnulib:
#ifdef _LIBC
# include <libc-lock.h>
#else
-/* Allow memory races; that's random enough. */
-# define __libc_lock_define_initialized(class, name)
-# define __libc_lock_lock(name) ((void) 0)
-# define __libc_lock_unlock(name) ((void) 0)
+# include "glthread/lock.h"
+# define __libc_lock_define_initialized gl_lock_define_initialized
+# define __libc_lock_lock gl_lock_lock
+# define __libc_lock_unlock gl_lock_unlock
#endif
/* An improved random number generation package. In addition to the standard
-# random.m4 serial 4
+# random.m4 serial 4.1
dnl Copyright (C) 2012-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,
AC_DEFUN([gl_FUNC_RANDOM],
[
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST])
dnl We can't use AC_CHECK_FUNC here, because random() is defined as a
dnl static inline function when compiling for Android 4.4 or older.
if test $ac_cv_func_setstate = no; then
HAVE_SETSTATE=0
fi
- if test $ac_cv_func_initstate = no || test $ac_cv_func_setstate = no; then
+ dnl On several platforms, random() is not multithread-safe.
+ if test $ac_cv_func_initstate = no || test $ac_cv_func_setstate = no \
+ || case "$host_os" in \
+ darwin* | freebsd* | solaris* | cygwin* | haiku*) true ;; \
+ *) false ;; \
+ esac
+ then
dnl In order to define initstate or setstate, we need to define all the
dnl functions at once.
REPLACE_RANDOM=1
m4/random.m4
Depends-on:
-libc-config [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]
stdlib
+libc-config [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]
+lock [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]
stdint [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]
random_r [test $HAVE_RANDOM = 0 || test $REPLACE_RANDOM = 1 || test $REPLACE_INITSTATE = 1 || test $REPLACE_SETSTATE = 1]