Module: wine Branch: master Commit: d5edadf35a40cb7238c2068db28b6c6abc7da800 URL: https://source.winehq.org/git/wine.git/?a=commit;h=d5edadf35a40cb7238c2068db...
Author: Akihiro Sagawa sagawa.aki@gmail.com Date: Fri Sep 25 00:07:50 2020 +0900
kernelbase: Improve Get{, Dynamic}TimeZoneInformation() performance.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49808 Signed-off-by: Akihiro Sagawa sagawa.aki@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernelbase/locale.c | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-)
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c index 4e7bd9937b..83dd76e3c0 100644 --- a/dlls/kernelbase/locale.c +++ b/dlls/kernelbase/locale.c @@ -4122,6 +4122,20 @@ INT WINAPI DECLSPEC_HOTPATCH GetCalendarInfoEx( const WCHAR *locale, CALID calen return GetCalendarInfoW( lcid, calendar, type, data, count, value ); }
+static CRITICAL_SECTION tzname_section; +static CRITICAL_SECTION_DEBUG tzname_section_debug = +{ + 0, 0, &locale_section, + { &tzname_section_debug.ProcessLocksList, &tzname_section_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": tzname_section") } +}; +static CRITICAL_SECTION tzname_section = { &tzname_section_debug, -1, 0, 0, 0, 0 }; +static struct { + LCID lcid; + WCHAR key_name[128]; + WCHAR standard_name[32]; + WCHAR daylight_name[32]; +} cached_tzname;
/*********************************************************************** * GetDynamicTimeZoneInformation (kernelbase.@) @@ -4134,15 +4148,34 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetDynamicTimeZoneInformation( DYNAMIC_TIME_ZONE_ if (!set_ntstatus( RtlQueryDynamicTimeZoneInformation( (RTL_DYNAMIC_TIME_ZONE_INFORMATION *)info ))) return TIME_ZONE_ID_INVALID;
- if (!RegOpenKeyExW( tz_key, info->TimeZoneKeyName, 0, KEY_ALL_ACCESS, &key )) + RtlEnterCriticalSection( &tzname_section ); + if (cached_tzname.lcid == GetThreadLocale() && + !wcscmp( info->TimeZoneKeyName, cached_tzname.key_name )) + { + wcscpy( info->StandardName, cached_tzname.standard_name ); + wcscpy( info->DaylightName, cached_tzname.daylight_name ); + RtlLeaveCriticalSection( &tzname_section ); + } + else { - RegLoadMUIStringW( key, L"MUI_Std", info->StandardName, - sizeof(info->StandardName), NULL, 0, system_dir ); - RegLoadMUIStringW( key, L"MUI_Dlt", info->DaylightName, - sizeof(info->DaylightName), NULL, 0, system_dir ); - RegCloseKey( key ); + RtlLeaveCriticalSection( &tzname_section ); + if (!RegOpenKeyExW( tz_key, info->TimeZoneKeyName, 0, KEY_ALL_ACCESS, &key )) + { + RegLoadMUIStringW( key, L"MUI_Std", info->StandardName, + sizeof(info->StandardName), NULL, 0, system_dir ); + RegLoadMUIStringW( key, L"MUI_Dlt", info->DaylightName, + sizeof(info->DaylightName), NULL, 0, system_dir ); + RegCloseKey( key ); + } + else return TIME_ZONE_ID_INVALID; + + RtlEnterCriticalSection( &tzname_section ); + cached_tzname.lcid = GetThreadLocale(); + wcscpy( cached_tzname.key_name, info->TimeZoneKeyName ); + wcscpy( cached_tzname.standard_name, info->StandardName ); + wcscpy( cached_tzname.daylight_name, info->DaylightName ); + RtlLeaveCriticalSection( &tzname_section ); } - else return TIME_ZONE_ID_INVALID;
NtQuerySystemTime( &now ); return get_timezone_id( (TIME_ZONE_INFORMATION *)info, now, FALSE );