diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c index c7546b1f78a..cd759018753 100644 --- a/dlls/ntdll/time.c +++ b/dlls/ntdll/time.c @@ -48,6 +48,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); +static CRITICAL_SECTION TIME_GetBias_section; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &TIME_GetBias_section, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { 0, (DWORD)(__FILE__ ": TIME_GetBias_section") } +}; +static CRITICAL_SECTION TIME_GetBias_section = { &critsect_debug, -1, 0, 0, 0, 0 }; + + #define SETTIME_MAX_ADJUST 120 /* This structure is used to store strings that represent all of the time zones @@ -481,11 +491,25 @@ BOOLEAN WINAPI RtlTimeFieldsToTime( */ static int TIME_GetBias(time_t utc, int *pdaylight) { - struct tm *ptm = localtime(&utc); - *pdaylight = ptm->tm_isdst; /* daylight for local timezone */ - ptm = gmtime(&utc); - ptm->tm_isdst = *pdaylight; /* use local daylight, not that of Greenwich */ - return (int)(utc-mktime(ptm)); + struct tm *ptm; + static time_t last_utc; + static int last_bias; + int ret; + + RtlEnterCriticalSection( &TIME_GetBias_section ); + if(utc == last_utc) + ret = last_bias; + else + { + ptm = localtime(&utc); + *pdaylight = ptm->tm_isdst; /* daylight for local timezone */ + ptm = gmtime(&utc); + ptm->tm_isdst = *pdaylight; /* use local daylight, not that of Greenwich */ + last_utc = utc; + ret = last_bias = (int)(utc-mktime(ptm)); + } + RtlLeaveCriticalSection( &TIME_GetBias_section ); + return ret; } /******************************************************************************