]> Savannah Git Hosting - gnulib.git/commitdiff
random: Fix multithread-safety bug.
authorBruno Haible <bruno@clisp.org>
Thu, 9 Nov 2023 14:56:32 +0000 (15:56 +0100)
committerBruno Haible <bruno@clisp.org>
Fri, 24 Nov 2023 07:27:22 +0000 (08:27 +0100)
* 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.

ChangeLog
doc/posix-functions/random.texi
lib/random.c
m4/random.m4
modules/random

index 83db185ad87d1873b3d1b7639d0f0941e864e6c3..396668b66c7345dd55dad6bf852b3644295812e5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+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.
index 19349617bef4a0cc3f486ddd5be6d3b30f583118..84cacbe8b5e41c4f6edf0f00500078a286b5a6ba 100644 (file)
@@ -15,7 +15,8 @@ mingw, MSVC 14.
 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:
index 50080ef2d5c2ac1fd83563683677eb84e4b54163..ac5999101aebf233340742cddda7deeea89d4e6d 100644 (file)
 #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
index 939a8440295cd73a2528a7de8399ed0a3cfdc6a2..5a2db0c1574953aab99a09c3a699275cc7826a45 100644 (file)
@@ -1,4 +1,4 @@
-# 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,
@@ -7,6 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
 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.
@@ -31,7 +32,13 @@ AC_DEFUN([gl_FUNC_RANDOM],
     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
index a6ccbb777dcb2e57c7f9f32d1526edc423518cbb..9774088bda2ab830b4786443f8364d344eb6ea87 100644 (file)
@@ -6,8 +6,9 @@ lib/random.c
 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]