[project @ 2001-08-04 06:11:24 by ken]
[ghc-hetmet.git] / ghc / lib / std / Time.hsc
index c1f12d1..fbfc0bd 100644 (file)
@@ -3,7 +3,7 @@
 -- to compile on sparc-solaris.  Blargh.
 
 -- -----------------------------------------------------------------------------
--- $Id: Time.hsc,v 1.12 2001/04/25 14:36:48 simonmar Exp $
+-- $Id: Time.hsc,v 1.19 2001/07/24 05:53:27 ken Exp $
 --
 -- (c) The University of Glasgow, 1995-2001
 --
@@ -92,34 +92,7 @@ module Time
 
      ) where
 
-#include "config.h"
-
-#if defined(HAVE_GETTIMEOFDAY)
-#  ifdef HAVE_SYS_TIME_H
-#   include <sys/time.h>
-#  endif
-#elif defined(HAVE_GETCLOCK)
-# ifdef HAVE_SYS_TIMERS_H
-#  define POSIX_4D9 1
-#  include <sys/timers.h>
-# endif
-#endif
-
-#if defined(HAVE_TIME_H)
-# include <time.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_SYS_TIMEB_H
-#include <sys/timeb.h>
-#endif
-
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
-#endif
+#include "HsStd.h"
 
 import Ix
 import Locale
@@ -236,8 +209,8 @@ noTimeDiff = TimeDiff 0 0 0 0 0 0 0
 getClockTime = do
   allocaBytes (#const sizeof(struct timeval)) $ \ p_timeval -> do
     throwErrnoIfMinus1_ "getClockTime" $ gettimeofday p_timeval nullPtr
-    sec  <- (#peek struct timeval,tv_sec)  p_timeval :: IO CLong
-    usec <- (#peek struct timeval,tv_usec) p_timeval :: IO CLong
+    sec  <- (#peek struct timeval,tv_sec)  p_timeval :: IO Int32
+    usec <- (#peek struct timeval,tv_usec) p_timeval :: IO Int32
     return (TOD (fromIntegral sec) ((fromIntegral usec) * 1000))
  
 #elif HAVE_FTIME
@@ -343,7 +316,7 @@ zone x      = (#peek struct tm,tm_zone) x
 gmtoff x    = (#peek struct tm,tm_gmtoff) x
 
 #else /* ! HAVE_TM_ZONE */
-# if HAVE_TZNAME || _WIN32
+# if HAVE_TZNAME || defined(_WIN32)
 #  if cygwin32_TARGET_OS
 #   define tzname _tzname
 #  endif
@@ -394,18 +367,40 @@ gmtoff x = do
 
 
 toCalendarTime :: ClockTime -> IO CalendarTime
-toCalendarTime =  clockToCalendarTime localtime False
+#if HAVE_LOCALTIME_R
+toCalendarTime =  clockToCalendarTime_reentrant (throwAwayReturnPointer localtime_r) False
+#else
+toCalendarTime =  clockToCalendarTime_static localtime False
+#endif
 
 toUTCTime      :: ClockTime -> CalendarTime
-toUTCTime      =  unsafePerformIO . clockToCalendarTime gmtime True
+#if HAVE_GMTIME_R
+toUTCTime      =  unsafePerformIO . clockToCalendarTime_reentrant (throwAwayReturnPointer gmtime_r) True
+#else
+toUTCTime      =  unsafePerformIO . clockToCalendarTime_static gmtime True
+#endif
 
--- ToDo: should be made thread safe, because localtime uses static storage,
--- or use the localtime_r version.
-clockToCalendarTime :: (Ptr CTime -> IO (Ptr CTm)) -> Bool -> ClockTime
+throwAwayReturnPointer :: (Ptr CTime -> Ptr CTm -> IO (Ptr CTm))
+                       -> (Ptr CTime -> Ptr CTm -> IO (       ))
+throwAwayReturnPointer fun x y = fun x y >> return ()
+
+clockToCalendarTime_static :: (Ptr CTime -> IO (Ptr CTm)) -> Bool -> ClockTime
         -> IO CalendarTime
-clockToCalendarTime fun is_utc (TOD secs psec) = do
+clockToCalendarTime_static fun is_utc (TOD secs psec) = do
   withObject (fromIntegral secs :: CTime)  $ \ p_timer -> do
     p_tm <- fun p_timer        -- can't fail, according to POSIX
+    clockToCalendarTime_aux is_utc p_tm psec
+
+clockToCalendarTime_reentrant :: (Ptr CTime -> Ptr CTm -> IO ()) -> Bool -> ClockTime
+        -> IO CalendarTime
+clockToCalendarTime_reentrant fun is_utc (TOD secs psec) = do
+  withObject (fromIntegral secs :: CTime)  $ \ p_timer -> do
+    allocaBytes (#const sizeof(struct tm)) $ \ p_tm -> do
+      fun p_timer p_tm
+      clockToCalendarTime_aux is_utc p_tm psec
+
+clockToCalendarTime_aux :: Bool -> Ptr CTm -> Integer -> IO CalendarTime
+clockToCalendarTime_aux is_utc p_tm psec = do
     sec   <-  (#peek struct tm,tm_sec  ) p_tm :: IO CInt
     min   <-  (#peek struct tm,tm_min  ) p_tm :: IO CInt
     hour  <-  (#peek struct tm,tm_hour ) p_tm :: IO CInt
@@ -620,10 +615,18 @@ formatTimeDiff l fmt td@(TimeDiff year month day hour min sec _)
 
 type CTm = () -- struct tm
 
-foreign import unsafe localtime :: Ptr CTime -> IO (Ptr CTm)
-foreign import unsafe gmtime    :: Ptr CTime -> IO (Ptr CTm)
-foreign import unsafe mktime    :: Ptr CTm   -> IO CTime
-foreign import unsafe time      :: Ptr CTime -> IO CTime
+#if HAVE_LOCALTIME_R
+foreign import unsafe localtime_r :: Ptr CTime -> Ptr CTm -> IO (Ptr CTm)
+#else
+foreign import unsafe localtime   :: Ptr CTime -> IO (Ptr CTm)
+#endif
+#if HAVE_GMTIME_R
+foreign import unsafe gmtime_r    :: Ptr CTime -> Ptr CTm -> IO (Ptr CTm)
+#else
+foreign import unsafe gmtime      :: Ptr CTime -> IO (Ptr CTm)
+#endif
+foreign import unsafe mktime      :: Ptr CTm   -> IO CTime
+foreign import unsafe time        :: Ptr CTime -> IO CTime
 
 #if HAVE_GETTIMEOFDAY
 type CTimeVal = ()