Alexandre Julliard : msvcrt: Return a per-thread buffer in localtime and gmtime.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Dec 21 14:26:10 CST 2005


Module: wine
Branch: refs/heads/master
Commit: 06c1a36bce839e06d0cb962f4b45bb1a2fc9dd55
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=06c1a36bce839e06d0cb962f4b45bb1a2fc9dd55

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Dec 21 20:54:26 2005 +0100

msvcrt: Return a per-thread buffer in localtime and gmtime.

---

 dlls/msvcrt/msvcrt.h |   25 ++++++++++----------
 dlls/msvcrt/time.c   |   64 +++++++++++++++++++++++++-------------------------
 2 files changed, 45 insertions(+), 44 deletions(-)

diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index b454579..68f5ca6 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -74,6 +74,18 @@ typedef void (*MSVCRT__beginthread_start
 typedef unsigned int (__stdcall *MSVCRT__beginthreadex_start_routine_t)(void *);
 typedef int (*MSVCRT__onexit_t)(void);
 
+struct MSVCRT_tm {
+    int tm_sec;
+    int tm_min;
+    int tm_hour;
+    int tm_mday;
+    int tm_mon;
+    int tm_year;
+    int tm_wday;
+    int tm_yday;
+    int tm_isdst;
+};
+
 
 /* TLS data */
 extern DWORD msvcrt_tls_index;
@@ -84,6 +96,7 @@ struct __thread_data {
     unsigned char                  *mbstok_next;        /* next ptr for mbstok() */
     char                           *efcvt_buffer;       /* buffer for ecvt/fcvt */
     MSVCRT_wchar_t                 *wasctime_buffer;    /* buffer for asctime */
+    struct MSVCRT_tm                time_buffer;        /* buffer for localtime/gmtime */
     int                             fpecode;
     MSVCRT_terminate_function       terminate_handler;
     MSVCRT_unexpected_function      unexpected_handler;
@@ -173,18 +186,6 @@ extern unsigned msvcrt_create_io_inherit
 #define _RT_CRNL        252
 #define _RT_BANNER      255
 
-struct MSVCRT_tm {
-    int tm_sec;
-    int tm_min;
-    int tm_hour;
-    int tm_mday;
-    int tm_mon;
-    int tm_year;
-    int tm_wday;
-    int tm_yday;
-    int tm_isdst;
-};
-
 struct MSVCRT__timeb {
     MSVCRT_time_t  time;
     unsigned short millitm;
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c
index f462aa7..9b26770 100644
--- a/dlls/msvcrt/time.c
+++ b/dlls/msvcrt/time.c
@@ -54,9 +54,6 @@ static inline int IsLeapYear(int Year)
 #define TICKSPERMSEC      10000
 #define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)
 
-/* native uses a single static buffer for localtime/gmtime/mktime */
-static struct MSVCRT_tm tm;
-
 /**********************************************************************
  *		mktime (MSVCRT.@)
  */
@@ -65,7 +62,7 @@ MSVCRT_time_t MSVCRT_mktime(struct MSVCR
     MSVCRT_time_t secs;
     FILETIME lft, uft;
     ULONGLONG time;
-    struct MSVCRT_tm ts;
+    struct MSVCRT_tm ts, *ptm;
     int cleaps, day;
 
     ts=*t;
@@ -125,7 +122,7 @@ MSVCRT_time_t MSVCRT_mktime(struct MSVCR
     secs = time - SECS_1601_TO_1970;
     /* compute tm_wday, tm_yday and renormalize the other fields of the
      * tm structure */
-    if( MSVCRT_localtime( &secs)) *t = tm;
+    if ((ptm = MSVCRT_localtime( &secs ))) *t = *ptm;
 
     return secs; 
 }
@@ -135,8 +132,8 @@ MSVCRT_time_t MSVCRT_mktime(struct MSVCR
  */
 struct MSVCRT_tm* MSVCRT_localtime(const MSVCRT_time_t* secs)
 {
+  thread_data_t * const data = msvcrt_get_thread_data();
   int i;
-
   FILETIME ft, lft;
   SYSTEMTIME st;
   DWORD tzid;
@@ -152,34 +149,37 @@ struct MSVCRT_tm* MSVCRT_localtime(const
 
   if (st.wYear < 1970) return NULL;
 
-  tm.tm_sec  = st.wSecond;
-  tm.tm_min  = st.wMinute;
-  tm.tm_hour = st.wHour;
-  tm.tm_mday = st.wDay;
-  tm.tm_year = st.wYear - 1900;
-  tm.tm_mon  = st.wMonth  - 1;
-  tm.tm_wday = st.wDayOfWeek;
+  data->time_buffer.tm_sec  = st.wSecond;
+  data->time_buffer.tm_min  = st.wMinute;
+  data->time_buffer.tm_hour = st.wHour;
+  data->time_buffer.tm_mday = st.wDay;
+  data->time_buffer.tm_year = st.wYear - 1900;
+  data->time_buffer.tm_mon  = st.wMonth  - 1;
+  data->time_buffer.tm_wday = st.wDayOfWeek;
 
-  for (i = tm.tm_yday = 0; i < st.wMonth - 1; i++) {
-    tm.tm_yday += MonthLengths[IsLeapYear(st.wYear)][i];
+  for (i = data->time_buffer.tm_yday = 0; i < st.wMonth - 1; i++) {
+    data->time_buffer.tm_yday += MonthLengths[IsLeapYear(st.wYear)][i];
   }
 
-  tm.tm_yday += st.wDay - 1;
+  data->time_buffer.tm_yday += st.wDay - 1;
  
   tzid = GetTimeZoneInformation(&tzinfo);
 
   if (tzid == TIME_ZONE_ID_INVALID)
-    tm.tm_isdst = -1;
+    data->time_buffer.tm_isdst = -1;
   else 
-    tm.tm_isdst = (tzid == TIME_ZONE_ID_DAYLIGHT?1:0);
+    data->time_buffer.tm_isdst = (tzid == TIME_ZONE_ID_DAYLIGHT?1:0);
 
-  return &tm;
+  return &data->time_buffer;
 }
 
+/*********************************************************************
+ *      gmtime (MSVCRT.@)
+ */
 struct MSVCRT_tm* MSVCRT_gmtime(const MSVCRT_time_t* secs)
 {
+  thread_data_t * const data = msvcrt_get_thread_data();
   int i;
-
   FILETIME ft;
   SYSTEMTIME st;
 
@@ -192,21 +192,21 @@ struct MSVCRT_tm* MSVCRT_gmtime(const MS
 
   if (st.wYear < 1970) return NULL;
 
-  tm.tm_sec  = st.wSecond;
-  tm.tm_min  = st.wMinute;
-  tm.tm_hour = st.wHour;
-  tm.tm_mday = st.wDay;
-  tm.tm_year = st.wYear - 1900;
-  tm.tm_mon  = st.wMonth - 1;
-  tm.tm_wday = st.wDayOfWeek;
-  for (i = tm.tm_yday = 0; i < st.wMonth - 1; i++) {
-    tm.tm_yday += MonthLengths[IsLeapYear(st.wYear)][i];
+  data->time_buffer.tm_sec  = st.wSecond;
+  data->time_buffer.tm_min  = st.wMinute;
+  data->time_buffer.tm_hour = st.wHour;
+  data->time_buffer.tm_mday = st.wDay;
+  data->time_buffer.tm_year = st.wYear - 1900;
+  data->time_buffer.tm_mon  = st.wMonth - 1;
+  data->time_buffer.tm_wday = st.wDayOfWeek;
+  for (i = data->time_buffer.tm_yday = 0; i < st.wMonth - 1; i++) {
+    data->time_buffer.tm_yday += MonthLengths[IsLeapYear(st.wYear)][i];
   }
 
-  tm.tm_yday += st.wDay - 1;
-  tm.tm_isdst = 0;
+  data->time_buffer.tm_yday += st.wDay - 1;
+  data->time_buffer.tm_isdst = 0;
 
-  return &tm;
+  return &data->time_buffer;
 }
 
 /**********************************************************************




More information about the wine-cvs mailing list