From: Benjamin Fischer <bfis@gmx.net> At least for glibc: localtime() calls always check for timezone configuration changes which usually includes a stat syscall, localtime_r() does not. --- dlls/ntdll/unix/system.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 148624ff405..d3de54deb1a 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -2694,12 +2694,12 @@ static int weekday_to_mday(int year, int day, int mon, int day_of_week) wday = 1; /* 1 - 1st, ...., 5 - last */ while (wday < day) { - struct tm *tm; + struct tm *tm, tmbuf; date.tm_mday += 7; date.tm_isdst = -1; tmp = mktime(&date); - tm = localtime(&tmp); + tm = localtime_r(&tmp, &tmbuf); if (tm->tm_mon != mon) break; mday = tm->tm_mday; @@ -2879,18 +2879,18 @@ static void find_reg_tz_info(RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi, int year) static time_t find_dst_change(time_t start, time_t end, int *is_dst) { - struct tm *tm; + struct tm *tm, tmbuf; ULONGLONG min = (sizeof(time_t) == sizeof(int)) ? (ULONG)start : start; ULONGLONG max = (sizeof(time_t) == sizeof(int)) ? (ULONG)end : end; time_t pos; - tm = localtime(&start); + tm = localtime_r(&start, &tmbuf); *is_dst = !tm->tm_isdst; TRACE("starting date isdst %d, %s", !*is_dst, ctime(&start)); for (pos = min; pos <= max; pos += 30 * 24 * 3600) { - tm = localtime(&pos); + tm = localtime_r(&pos, &tmbuf); if (tm->tm_isdst == *is_dst) { max = pos; @@ -2901,7 +2901,7 @@ static time_t find_dst_change(time_t start, time_t end, int *is_dst) while (min <= max) { pos = (min + max) / 2; - tm = localtime(&pos); + tm = localtime_r(&pos, &tmbuf); if (tm->tm_isdst != *is_dst) min = pos + 1; @@ -3000,7 +3000,7 @@ static void get_timezone_info( RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi ) static RTL_DYNAMIC_TIME_ZONE_INFORMATION cached_tzi; static int current_year = -1, current_bias = 65535; RTL_DYNAMIC_TIME_ZONE_INFORMATION reg_tzi; - struct tm *tm, tm1, tm2; + struct tm *tm, tmbuf, tm1, tm2; time_t year_start, year_end, tmp, dlt = 0, std = 0; int is_dst, bias; BOOL inverted_dst; @@ -3011,7 +3011,7 @@ static void get_timezone_info( RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi ) tm = gmtime(&year_start); bias = (LONG)(mktime(tm) - year_start) / 60; - tm = localtime(&year_start); + tm = localtime_r(&year_start, &tmbuf); if (current_year == tm->tm_year && current_bias == bias) { *tzi = cached_tzi; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10892