changeset 13382:64c19ce2ffa0

time: work with mingw + pthreads-win32 library When using the pthreads-win32 library with mingw, struct timespec is available in <pthread.h>. Meanwhile, that header has some rather buggy macros for localtime_r and gmtime_r that interfere with proper gnulib replacement header actions. Tested in a cross-compilation environment: Fedora 13 with mingw32-gcc and mingw32-pthreads installed. * m4/time_h.m4 (gl_CHECK_TYPE_STRUCT_TIMESPEC): Set new variable if timespec is defined only in pthread.h. * modules/time (Makefile.am): Substitute it. * lib/time.in.h (!TIME_H_DEFINES_STRUCT_TIMESPEC): Include <pthread.h>, when needed. (GNULIB_TIME_R): Undefine broken localtime_r and gmtime_r macros from the library. Signed-off-by: Eric Blake <eblake@redhat.com>
author Eric Blake <eblake@redhat.com>
date Wed, 02 Jun 2010 11:08:06 -0600
parents 25bed74b17cc
children 27aa5a0e75a5
files ChangeLog lib/time.in.h m4/time_h.m4 modules/time
diffstat 4 files changed, 36 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-06-02  Eric Blake  <eblake@redhat.com>
+
+	time: work with mingw + pthreads-win32 library
+	* m4/time_h.m4 (gl_CHECK_TYPE_STRUCT_TIMESPEC): Set new variable
+	if timespec is defined only in pthread.h.
+	* modules/time (Makefile.am): Substitute it.
+	* lib/time.in.h (!TIME_H_DEFINES_STRUCT_TIMESPEC): Include
+	<pthread.h>, when needed.
+	(GNULIB_TIME_R): Undefine broken localtime_r and gmtime_r macros
+	from the library.
+
 2010-05-31  Bruno Haible  <bruno@clisp.org>
 
 	Avoid expanding two macros in the wrong order.
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -48,10 +48,13 @@
 
 /* Some systems don't define struct timespec (e.g., AIX 4.1, Ultrix 4.3).
    Or they define it with the wrong member names or define it in <sys/time.h>
-   (e.g., FreeBSD circa 1997).  */
+   (e.g., FreeBSD circa 1997).  Stock Mingw does not define it, but the
+   pthreads-win32 library defines it in <pthread.h>.  */
 # if ! @TIME_H_DEFINES_STRUCT_TIMESPEC@
 #  if @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
 #   include <sys/time.h>
+#  elif @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+#   include <pthread.h>
 #  else
 
 #   ifdef __cplusplus
@@ -128,6 +131,7 @@
                                              struct tm *restrict __result));
 #  else
 #   if ! @HAVE_LOCALTIME_R@
+#    undef localtime_r
 _GL_FUNCDECL_SYS (localtime_r, struct tm *, (time_t const *restrict __timer,
                                              struct tm *restrict __result)
                                             _GL_ARG_NONNULL ((1, 2)));
@@ -148,6 +152,7 @@
                                           struct tm *restrict __result));
 #  else
 #   if ! @HAVE_LOCALTIME_R@
+#    undef gmtime_r
 _GL_FUNCDECL_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer,
                                           struct tm *restrict __result)
                                          _GL_ARG_NONNULL ((1, 2)));
--- a/m4/time_h.m4
+++ b/m4/time_h.m4
@@ -2,6 +2,8 @@
 
 # Copyright (C) 2000-2001, 2003-2007, 2009-2010 Free Software Foundation, Inc.
 
+# serial 2
+
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -24,7 +26,7 @@
 ])
 
 dnl Define HAVE_STRUCT_TIMESPEC if `struct timespec' is declared
-dnl in time.h or sys/time.h.
+dnl in time.h, sys/time.h, or pthread.h.
 
 AC_DEFUN([gl_CHECK_TYPE_STRUCT_TIMESPEC],
 [
@@ -41,6 +43,7 @@
 
   TIME_H_DEFINES_STRUCT_TIMESPEC=0
   SYS_TIME_H_DEFINES_STRUCT_TIMESPEC=0
+  PTHREAD_H_DEFINES_STRUCT_TIMESPEC=0
   if test $gl_cv_sys_struct_timespec_in_time_h = yes; then
     TIME_H_DEFINES_STRUCT_TIMESPEC=1
   else
@@ -55,10 +58,24 @@
          [gl_cv_sys_struct_timespec_in_sys_time_h=no])])
     if test $gl_cv_sys_struct_timespec_in_sys_time_h = yes; then
       SYS_TIME_H_DEFINES_STRUCT_TIMESPEC=1
+    else
+      AC_CACHE_CHECK([for struct timespec in <pthread.h>],
+        [gl_cv_sys_struct_timespec_in_pthread_h],
+        [AC_COMPILE_IFELSE(
+           [AC_LANG_PROGRAM(
+              [[#include <pthread.h>
+              ]],
+              [[static struct timespec x; x.tv_sec = x.tv_nsec;]])],
+           [gl_cv_sys_struct_timespec_in_pthread_h=yes],
+           [gl_cv_sys_struct_timespec_in_pthread_h=no])])
+      if test $gl_cv_sys_struct_timespec_in_pthread_h = yes; then
+        PTHREAD_H_DEFINES_STRUCT_TIMESPEC=1
+      fi
     fi
   fi
   AC_SUBST([TIME_H_DEFINES_STRUCT_TIMESPEC])
   AC_SUBST([SYS_TIME_H_DEFINES_STRUCT_TIMESPEC])
+  AC_SUBST([PTHREAD_H_DEFINES_STRUCT_TIMESPEC])
 ])
 
 AC_DEFUN([gl_TIME_MODULE_INDICATOR],
--- a/modules/time
+++ b/modules/time
@@ -40,6 +40,7 @@
 	      -e 's|@''REPLACE_MKTIME''@|$(REPLACE_MKTIME)|g' \
 	      -e 's|@''REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \
 	      -e 's|@''REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|g' \
+	      -e 's|@''PTHREAD_H_DEFINES_STRUCT_TIMESPEC''@|$(PTHREAD_H_DEFINES_STRUCT_TIMESPEC)|g' \
 	      -e 's|@''SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
 	      -e 's|@''TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \