bug-gnulib
[Top][All Lists]
Advanced

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

Re: [bug-gnulib] localtime_r thread-safe?


From: Bruno Haible
Subject: Re: [bug-gnulib] localtime_r thread-safe?
Date: Thu, 27 Apr 2006 15:43:50 +0200
User-agent: KMail/1.5

teedee wrote on 2006-03-27:
> Is localtime_r thread-safe? If it's not, what's the alternative for this
> function call?

localtime_r is thread-safe if the system provides it and it has the POSIX
prototype: struct tm * localtime_r (const time_t *, struct tm *);
In the other cases, gnulib provides a replacement that has the right prototype
but is not thread-safe.

The alternative is to use the time() function and convert to local time 
yourself.

Paul, what about the following patch to make our replacement functions MT-safe?


2006-04-27  Bruno Haible  <address@hidden>

        Make gmtime_r and localtime_r replacements multithread-safe.
        * time_r.c: Include lock.h.
        (bufferlock): New variable.
        (gmtime_r, localtime_r): Protect against concurrent use.
        * modules/time_r: Depend on module lock.

diff -c -3 -r1.6 time_r.c
*** lib/time_r.c        25 Mar 2006 04:36:14 -0000      1.6
--- lib/time_r.c        27 Apr 2006 13:42:37 -0000
***************
*** 25,30 ****
--- 25,31 ----
  #include "time_r.h"
  
  #include <string.h>
+ #include "lock.h"
  
  static struct tm *
  copy_tm_result (struct tm *dest, struct tm const *src)
***************
*** 35,49 ****
    return dest;
  }
  
  
  struct tm *
  gmtime_r (time_t const * restrict t, struct tm * restrict tp)
  {
!   return copy_tm_result (tp, gmtime (t));
  }
  
  struct tm *
  localtime_r (time_t const * restrict t, struct tm * restrict tp)
  {
!   return copy_tm_result (tp, localtime (t));
  }
--- 36,64 ----
    return dest;
  }
  
+ /* A lock protecting the static buffers holding the return values of
+    gmtime() and localtime().  We use a single lock, not two locks, because
+    it might be a single buffer for both functions.  */
+ gl_lock_define_initialized(static, bufferlock)
  
  struct tm *
  gmtime_r (time_t const * restrict t, struct tm * restrict tp)
  {
!   struct tm *result;
! 
!   gl_lock_lock (bufferlock);
!   result = copy_tm_result (tp, gmtime (t));
!   gl_lock_unlock (bufferlock);
!   return result;
  }
  
  struct tm *
  localtime_r (time_t const * restrict t, struct tm * restrict tp)
  {
!   struct tm *result;
! 
!   gl_lock_lock (bufferlock);
!   result = copy_tm_result (tp, localtime (t));
!   gl_lock_unlock (bufferlock);
!   return result;
  }
diff -c -3 -r1.6 time_r
*** modules/time_r      12 Apr 2006 16:50:51 -0000      1.6
--- modules/time_r      27 Apr 2006 13:42:37 -0000
***************
*** 7,12 ****
--- 7,13 ----
  m4/time_r.m4
  
  Depends-on:
+ lock
  extensions
  restrict
  





reply via email to

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