From 2eba343b51e0923cd3fb919a6abd6120590fc059 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 9 Jun 2020 08:17:12 -0700 Subject: Export of internal Abseil changes -- baf626d27ff1547776745f3b601cc42f703d4bdf by Greg Falcon : Import of CCTZ from GitHub. PiperOrigin-RevId: 315486679 -- 39d4e7f9214c5a74e4ee4b8a7f4af26479925029 by Gennadiy Rozental : Avoid order dependant test cases. PiperOrigin-RevId: 315327948 -- 8feb187703a28bb0c5cfc5dd6091e3faa90a8e61 by Gennadiy Rozental : Avoid order dependant test cases. PiperOrigin-RevId: 315317018 -- cffd8fddad15908ec9de7f21f65b20528972e3fa by Gennadiy Rozental : Avoid order dependant test cases. PiperOrigin-RevId: 315311587 -- 48997a0ceb231b75c14eb4b1eb3b66af69e49f42 by Tom Manshreck : Nit: remove extra "the" PiperOrigin-RevId: 314959763 -- 9516f44a4b5d3055427c95e80c8c04a6321e4221 by Gennadiy Rozental : Import of CCTZ from GitHub. PiperOrigin-RevId: 314925147 -- 4f8691d74a4eb42ed03ef29c9588a01b78829941 by Abseil Team : Uninclude util/bits/bits.h PiperOrigin-RevId: 314858384 -- 02b42a8ec5e5561b29b4e5f93cc1482c3c72ef2d by Abseil Team : Google-internal changes only. PiperOrigin-RevId: 314855667 -- 146013d69dabafbe2030e23ced7b741d9e8d417c by Gennadiy Rozental : Uninclude util/bits/bits.h PiperOrigin-RevId: 314838927 GitOrigin-RevId: baf626d27ff1547776745f3b601cc42f703d4bdf Change-Id: I2602286fb13cf35a88bdd80fe0b44974d4388d46 --- absl/time/internal/cctz/src/time_zone_impl.cc | 34 ++++++++++----------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'absl/time/internal/cctz/src/time_zone_impl.cc') diff --git a/absl/time/internal/cctz/src/time_zone_impl.cc b/absl/time/internal/cctz/src/time_zone_impl.cc index 030ae0e1..f34e3aec 100644 --- a/absl/time/internal/cctz/src/time_zone_impl.cc +++ b/absl/time/internal/cctz/src/time_zone_impl.cc @@ -15,6 +15,7 @@ #include "time_zone_impl.h" #include +#include #include #include #include @@ -48,17 +49,16 @@ std::mutex& TimeZoneMutex() { time_zone time_zone::Impl::UTC() { return time_zone(UTCImpl()); } bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { - const time_zone::Impl* const utc_impl = UTCImpl(); + const Impl* const utc_impl = UTCImpl(); - // First check for UTC (which is never a key in time_zone_map). + // Check for UTC (which is never a key in time_zone_map). auto offset = seconds::zero(); if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) { *tz = time_zone(utc_impl); return true; } - // Then check, under a shared lock, whether the time zone has already - // been loaded. This is the common path. TODO: Move to shared_mutex. + // Check whether the time zone has already been loaded. { std::lock_guard lock(TimeZoneMutex()); if (time_zone_map != nullptr) { @@ -70,20 +70,15 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { } } - // Now check again, under an exclusive lock. + // Load the new time zone (outside the lock). + std::unique_ptr new_impl(new Impl(name)); + + // Add the new time zone to the map. std::lock_guard lock(TimeZoneMutex()); if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName; const Impl*& impl = (*time_zone_map)[name]; - if (impl == nullptr) { - // The first thread in loads the new time zone. - Impl* new_impl = new Impl(name); - new_impl->zone_ = TimeZoneIf::Load(new_impl->name_); - if (new_impl->zone_ == nullptr) { - delete new_impl; // free the nascent Impl - impl = utc_impl; // and fallback to UTC - } else { - impl = new_impl; // install new time zone - } + if (impl == nullptr) { // this thread won any load race + impl = new_impl->zone_ ? new_impl.release() : utc_impl; } *tz = time_zone(impl); return impl != utc_impl; @@ -104,14 +99,11 @@ void time_zone::Impl::ClearTimeZoneMapTestOnly() { } } -time_zone::Impl::Impl(const std::string& name) : name_(name) {} +time_zone::Impl::Impl(const std::string& name) + : name_(name), zone_(TimeZoneIf::Load(name_)) {} const time_zone::Impl* time_zone::Impl::UTCImpl() { - static Impl* utc_impl = [] { - Impl* impl = new Impl("UTC"); - impl->zone_ = TimeZoneIf::Load(impl->name_); // never fails - return impl; - }(); + static const Impl* utc_impl = new Impl("UTC"); // never fails return utc_impl; } -- cgit v1.2.3