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 <[EMAIL PROTECTED]> 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