bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bug#64937: "who" reports funny dates


From: Bruno Haible
Subject: Re: bug#64937: "who" reports funny dates
Date: Fri, 04 Aug 2023 14:52:11 +0200

Paul Eggert wrote:
>  0006-readutmp-switch-new-struct-to-struct-timespec.patch

>  get_boot_time (void)
>  {
> -  static int cached;
> -  static struct timeval boot_time;
> +  static bool cached;
> +  static struct timespec boot_time;
>  
>    if (!cached)
>      {
> +      cached = true;
>        boot_time = get_boot_time_uncached ();
> -      cached = 1;
>      }
>    return boot_time;
>  }

This code is meant to be multithread-safe. Therefore it is important that
the 'cached' variable is set to true *after* the cache has been filled,
not before. Otherwise, when two threads call this code at nearly the same
time, the first one will set 'cached' to true, and the second one will
access the 'boot_time's value, which at this moment is still uninitialized.
In this situation, it is better that both threads compute the boot time
independently; they will produce the same result.


2023-08-04  Bruno Haible  <bruno@clisp.org>

        readutmp: Ensure multithread-safety.
        * lib/readutmp.c (get_boot_time): Initialize 'cached' after 'boot_time',
        not before. Also declare both as volatile.

diff --git a/lib/readutmp.c b/lib/readutmp.c
index c692b3854d..01c02ad36e 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -152,13 +152,13 @@ get_boot_time_uncached (void)
 static struct timespec
 get_boot_time (void)
 {
-  static bool cached;
-  static struct timespec boot_time;
+  static bool volatile cached;
+  static struct timespec volatile boot_time;
 
   if (!cached)
     {
-      cached = true;
       boot_time = get_boot_time_uncached ();
+      cached = true;
     }
   return boot_time;
 }






reply via email to

[Prev in Thread] Current Thread [Next in Thread]