This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, libgfortran] PR 40190 DATE_AND_TIME not thread-safe


Hi,

the attached patch fixes PR 40190 by using localtime_r and gmtime_r
instead of the non-reentrant variants.

The questionable thing about the current patch is that it assumes that
the _r functions are available on all gfortran targets. If this turns
out to not be the case, I'll do a follow-up patch [1]with a configure
check and a fallback implementation. However the _r functions were
added to POSIX already in SUSv2, so maybe it's not too much to ask.

Regtested on x86_64-unknown-linux-gnu, Ok for trunk?

[1] I have this partially done, but I'm not able to regenerate
configure properly, it bombs out with

/home/janne/src/gfortran/trunk/trunk-git/libgfortran/configure: line
15664: syntax error near unexpected token `gstdint.h'
/home/janne/src/gfortran/trunk/trunk-git/libgfortran/configure: line
15664: `GCC_HEADER_STDINT(gstdint.h)'

Anyone seen something similar? Commenting out the
GCC_HEADER_STDINT(gstdint.h) line in configure.ac (line 65) fixes
this, but supposedly it has been added for some reason at some point.

-- 
Janne Blomqvist

Attachment: ChangeLog
Description: Binary data

diff --git a/libgfortran/intrinsics/date_and_time.c b/libgfortran/intrinsics/date_and_time.c
index 9cfa9e8..5995102 100644
--- a/libgfortran/intrinsics/date_and_time.c
+++ b/libgfortran/intrinsics/date_and_time.c
@@ -166,8 +166,8 @@ date_and_time (char *__date, char *__time, char *__zone,
 
   if (lt != (time_t) -1)
     {
-      local_time = *localtime (&lt);
-      UTC_time = *gmtime (&lt);
+      localtime_r (&lt, &local_time);
+      gmtime_r (&lt, &UTC_time);
 
       /* All arguments can be derived from VALUES.  */
       values[0] = 1900 + local_time.tm_year;
@@ -361,7 +361,7 @@ itime0 (int x[3])
 
   if (lt != (time_t) -1)
     {
-      local_time = *localtime (&lt);
+      localtime_r (&lt, &local_time);
 
       x[0] = local_time.tm_hour;
       x[1] = local_time.tm_min;
@@ -443,7 +443,7 @@ idate0 (int x[3])
 
   if (lt != (time_t) -1)
     {
-      local_time = *localtime (&lt);
+      localtime_r (&lt, &local_time);
 
       x[0] = local_time.tm_mday;
       x[1] = 1 + local_time.tm_mon;
@@ -510,7 +510,7 @@ idate_i8 (gfc_array_i8 *__values)
 /* GMTIME(STIME, TARRAY) - Non-standard
 
    Description: Given a system time value STime, fills TArray with values
-   extracted from it appropriate to the GMT time zone using gmtime(3).
+   extracted from it appropriate to the GMT time zone using gmtime_r(3).
 
    The array elements are as follows:
 
@@ -530,7 +530,7 @@ gmtime_0 (const time_t * t, int x[9])
 {
   struct tm lt;
 
-  lt = *gmtime (t);
+  gmtime_r (t, &lt);
   x[0] = lt.tm_sec;
   x[1] = lt.tm_min;
   x[2] = lt.tm_hour;
@@ -602,7 +602,7 @@ gmtime_i8 (GFC_INTEGER_8 * t, gfc_array_i8 * tarray)
 /* LTIME(STIME, TARRAY) - Non-standard
 
    Description: Given a system time value STime, fills TArray with values
-   extracted from it appropriate to the local time zone using localtime(3).
+   extracted from it appropriate to the local time zone using localtime_r(3).
 
    The array elements are as follows:
 
@@ -622,7 +622,7 @@ ltime_0 (const time_t * t, int x[9])
 {
   struct tm lt;
 
-  lt = *localtime (t);
+  localtime_r (t, &lt);
   x[0] = lt.tm_sec;
   x[1] = lt.tm_min;
   x[2] = lt.tm_hour;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]