This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc 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]

mktime.c fixes (part 6 of 6): thread-safe support for non-glibc hosts


This last patch cleans up mktime.c so that it can use localtime_r when
available, allowing mktime to be invoked from multithreaded
applications even on non-glibc hosts.

A similar patch is needed for strftime.c and timegm.c; it is also
enclosed below.

If this patch is applied along with the earlier ones, timegm.c and
mktime.c will be identical in gnulib and glibc.  strftime.c won't be
identical, as it has some other fixes, but that is a topic for a
different series of messages, some other time.  I haven't tested this
particular strftime.c patch (only the strftime.c version in gnulib)
but it should be OK.


2003-12-30  Paul Eggert  <eggert@twinsun.com>

	* time/mktime.c: (my_mktime_localtime_r):
	Remove.  All uses changed to __localtime_r.
	(__localtime_r) [!defined _LIBC]: New macro.  Include "time_r.h" to
	get its implementation.
	Fix compile-command to allow for TIME_R_POSIX.

	* time/strftime.c (my_strftime_gmtime_r, my_strftime_localtime_r):
	Remove.  All uses changed to __localtime_r and __gmtime_r.
	(__gmtime_r, __localtime_r) [!HAVE_TM_GMTOFF]: New macros.
	Include "time_r.h" to get their implementations.

	* time/timegm.c: Allow use in GNU applications outside glibc.
	[defined HAVE_CONFIG_H]: Include <config.h>.
	[!defined _LIBC]: Include "timegm.h", <time_r.h>.
	Define __gmtime_r, and declare __mktime_internal.
	(timegm): Define via a prototype, since we can safely assume C89 now.

===================================================================
RCS file: RCS/mktime.c,v
retrieving revision 1.51.0.5
retrieving revision 1.51.0.7
diff -pu -r1.51.0.5 -r1.51.0.7
--- mktime.c	2003/12/31 06:33:41	1.51.0.5
+++ mktime.c	2003/12/31 07:12:54	1.51.0.7
@@ -101,22 +101,15 @@ const unsigned short int __mon_yday[2][1
   };
 
 
-#ifdef _LIBC
-# define my_mktime_localtime_r __localtime_r
-#else
-/* If we're a mktime substitute in a GNU program, then prefer
-   localtime to localtime_r, since many localtime_r implementations
-   are buggy.  */
-static struct tm *
-my_mktime_localtime_r (const time_t *t, struct tm *tp)
-{
-  struct tm *l = localtime (t);
-  if (! l)
-    return 0;
-  *tp = *l;
-  return tp;
-}
-#endif /* ! _LIBC */
+#ifndef _LIBC
+/* Portable standalone applications should supply a "time_r.h" that
+   declares a POSIX-compliant localtime_r, for the benefit of older
+   implementations that lack localtime_r or have a nonstandard one.
+   See the gnulib time_r module for one way to implement this.  */
+# include "time_r.h"
+# undef __localtime_r
+# define __localtime_r localtime_r
+#endif
 
 /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
    (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
@@ -239,9 +232,6 @@ ranged_convert (struct tm *(*convert) (c
    Use *OFFSET to keep track of a guess at the offset of the result,
    compared to what the result would be for UTC without leap seconds.
    If *OFFSET's guess is correct, only one CONVERT call is needed.  */
-#ifndef _LIBC
-static
-#endif
 time_t
 __mktime_internal (struct tm *tp,
 		   struct tm *(*convert) (const time_t *, struct tm *),
@@ -481,7 +471,7 @@ mktime (struct tm *tp)
   __tzset ();
 #endif
 
-  return __mktime_internal (tp, my_mktime_localtime_r, &localtime_offset);
+  return __mktime_internal (tp, __localtime_r, &localtime_offset);
 }
 
 #ifdef weak_alias
@@ -630,6 +620,6 @@ main (int argc, char **argv)
 
 /*
 Local Variables:
-compile-command: "gcc -DDEBUG -Wall -W -O -g mktime.c -o mktime"
+compile-command: "gcc -DDEBUG -DHAVE_TIME_R_POSIX -Wall -W -O -g mktime.c -o mktime"
 End:
 */
===================================================================
RCS file: RCS/strftime.c,v
retrieving revision 1.95
retrieving revision 1.95.0.1
diff -pu -r1.95 -r1.95.0.1
--- strftime.c	2003/06/13 02:53:26	1.95
+++ strftime.c	2003/12/31 07:03:03	1.95.0.1
@@ -167,44 +167,22 @@ extern char *tzname[];
 
 
 #ifdef _LIBC
-# define my_strftime_gmtime_r __gmtime_r
-# define my_strftime_localtime_r __localtime_r
 # define tzname __tzname
 # define tzset __tzset
-#else
-
-/* If we're a strftime substitute in a GNU program, then prefer gmtime
-   to gmtime_r, since many gmtime_r implementations are buggy.
-   Similarly for localtime_r.  */
-
-# if ! HAVE_TM_GMTOFF
-static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
-static struct tm *
-my_strftime_gmtime_r (t, tp)
-     const time_t *t;
-     struct tm *tp;
-{
-  struct tm *l = gmtime (t);
-  if (! l)
-    return 0;
-  *tp = *l;
-  return tp;
-}
-# endif /* ! HAVE_TM_GMTOFF */
+#endif
 
-static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
-static struct tm *
-my_strftime_localtime_r (t, tp)
-     const time_t *t;
-     struct tm *tp;
-{
-  struct tm *l = localtime (t);
-  if (! l)
-    return 0;
-  *tp = *l;
-  return tp;
-}
-#endif /* ! defined _LIBC */
+#if !HAVE_TM_GMTOFF
+/* Portable standalone applications should supply a "time_r.h" that
+   declares a POSIX-compliant localtime_r, for the benefit of older
+   implementations that lack localtime_r or have a nonstandard one.
+   Similarly for gmtime_r.  See the gnulib time_r module for one way
+   to implement this.  */
+# include "time_r.h"
+# undef __gmtime_r
+# undef __localtime_r
+# define __gmtime_r gmtime_r
+# define __localtime_r localtime_r
+#endif
 
 
 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
@@ -1388,7 +1366,7 @@ my_strftime (s, maxsize, format, tp ut_a
 		       occurred.  */
 		    struct tm tm;
 
-		    if (! my_strftime_localtime_r (&lt, &tm)
+		    if (! __localtime_r (&lt, &tm)
 			|| ((ltm.tm_sec ^ tm.tm_sec)
 			    | (ltm.tm_min ^ tm.tm_min)
 			    | (ltm.tm_hour ^ tm.tm_hour)
@@ -1398,7 +1376,7 @@ my_strftime (s, maxsize, format, tp ut_a
 		      break;
 		  }
 
-		if (! my_strftime_gmtime_r (&lt, &gtm))
+		if (! __gmtime_r (&lt, &gtm))
 		  break;
 
 		diff = tm_diff (&ltm, &gtm);
===================================================================
RCS file: RCS/timegm.c,v
retrieving revision 1.6
retrieving revision 1.6.0.1
diff -pu -r1.6 -r1.6.0.1
--- timegm.c	2003/09/03 20:17:08	1.6
+++ timegm.c	2003/12/31 06:59:27	1.6.0.1
@@ -1,4 +1,6 @@
-/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+/* Convert UTC calendar time to simple time.  Like mktime but assumes UTC.
+
+   Copyright (C) 1994, 1997, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -16,11 +18,29 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <time.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef _LIBC
+# include <time.h>
+#else
+# include "timegm.h"
+
+/* Portable standalone applications should supply a "time_r.h" that
+   declares a POSIX-compliant gmtime_r, for the benefit of older
+   implementations that lack gmtime_r or have a nonstandard one.
+   See the gnulib time_r module for one way to implement this.  */
+# include <time_r.h>
+# undef __gmtime_r
+# define __gmtime_r gmtime_r
+time_t __mktime_internal (struct tm *,
+			  struct tm * (*) (time_t const *, struct tm *),
+			  time_t *);
+#endif
 
 time_t
-timegm (tmp)
-     struct tm *const tmp;
+timegm (struct tm *tmp)
 {
   static time_t gmtime_offset;
   tmp->tm_isdst = 0;


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