From b31c11bca54b1f8a61c182b628b2f8618bb41a48 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sat, 24 Aug 2024 12:07:24 -0400 Subject: [PATCH] LibUnicode: Cache the system time zone It's expensive to determine the system time zone from disk each time it is requested. This makes LibUnicode cache the result, and provides an API to clear that cache. This will let us set up a monitor to watch for system time zone changes in platform-dependent ways. --- Tests/LibCore/TestLibCoreDateTime.cpp | 3 +++ Tests/LibJS/test-js.cpp | 2 ++ Tests/LibUnicode/TestTimeZone.cpp | 2 ++ Userland/Libraries/LibUnicode/TimeZone.cpp | 15 +++++++++++++-- Userland/Libraries/LibUnicode/TimeZone.h | 8 +++++++- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Tests/LibCore/TestLibCoreDateTime.cpp b/Tests/LibCore/TestLibCoreDateTime.cpp index 29017a8482e..22bd928cfc5 100644 --- a/Tests/LibCore/TestLibCoreDateTime.cpp +++ b/Tests/LibCore/TestLibCoreDateTime.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include class TimeZoneGuard { @@ -29,12 +30,14 @@ public: else TRY_OR_FAIL(Core::Environment::unset("TZ"sv)); + Unicode::clear_system_time_zone_cache(); tzset(); } void update(StringView time_zone) { TRY_OR_FAIL(Core::Environment::set("TZ"sv, time_zone, Core::Environment::Overwrite::Yes)); + Unicode::clear_system_time_zone_cache(); tzset(); } diff --git a/Tests/LibJS/test-js.cpp b/Tests/LibJS/test-js.cpp index 538b6fd4bad..9b2d15e4fa3 100644 --- a/Tests/LibJS/test-js.cpp +++ b/Tests/LibJS/test-js.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -106,6 +107,7 @@ TESTJS_GLOBAL_FUNCTION(set_time_zone, setTimeZone) return vm.throw_completion(MUST(String::formatted("Could not set time zone: {}", result.error()))); } + Unicode::clear_system_time_zone_cache(); tzset(); return current_time_zone; diff --git a/Tests/LibUnicode/TestTimeZone.cpp b/Tests/LibUnicode/TestTimeZone.cpp index 214b7ead4ae..208a0b90137 100644 --- a/Tests/LibUnicode/TestTimeZone.cpp +++ b/Tests/LibUnicode/TestTimeZone.cpp @@ -16,6 +16,7 @@ public: : m_time_zone(Core::Environment::get("TZ"sv)) { MUST(Core::Environment::set("TZ"sv, time_zone, Core::Environment::Overwrite::Yes)); + Unicode::clear_system_time_zone_cache(); } ~TimeZoneGuard() @@ -24,6 +25,7 @@ public: MUST(Core::Environment::set("TZ"sv, *m_time_zone, Core::Environment::Overwrite::Yes)); else MUST(Core::Environment::unset("TZ"sv)); + Unicode::clear_system_time_zone_cache(); } private: diff --git a/Userland/Libraries/LibUnicode/TimeZone.cpp b/Userland/Libraries/LibUnicode/TimeZone.cpp index e6fdcb5c882..5b270ed3e84 100644 --- a/Userland/Libraries/LibUnicode/TimeZone.cpp +++ b/Userland/Libraries/LibUnicode/TimeZone.cpp @@ -15,8 +15,13 @@ namespace Unicode { -String current_time_zone() +static Optional cached_system_time_zone; + +String current_time_zone(UseTimeZoneCache) { + if (cached_system_time_zone.has_value()) + return *cached_system_time_zone; + UErrorCode status = U_ZERO_ERROR; auto time_zone = adopt_own_if_nonnull(icu::TimeZone::detectHostTimeZone()); @@ -32,7 +37,13 @@ String current_time_zone() if (icu_failure(status)) return "UTC"_string; - return icu_string_to_string(time_zone_name); + cached_system_time_zone = icu_string_to_string(time_zone_name); + return *cached_system_time_zone; +} + +void clear_system_time_zone_cache() +{ + cached_system_time_zone.clear(); } // https://github.com/unicode-org/icu/blob/main/icu4c/source/tools/tzcode/icuzones diff --git a/Userland/Libraries/LibUnicode/TimeZone.h b/Userland/Libraries/LibUnicode/TimeZone.h index 41578b72705..2ccf036b43f 100644 --- a/Userland/Libraries/LibUnicode/TimeZone.h +++ b/Userland/Libraries/LibUnicode/TimeZone.h @@ -23,7 +23,13 @@ struct TimeZoneOffset { InDST in_dst { InDST::No }; }; -String current_time_zone(); +enum class UseTimeZoneCache { + No, + Yes, +}; + +String current_time_zone(UseTimeZoneCache = UseTimeZoneCache::Yes); +void clear_system_time_zone_cache(); Vector const& available_time_zones(); Vector available_time_zones_in_region(StringView region); Optional resolve_primary_time_zone(StringView time_zone);