brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · ead64e6 Raw
105 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html10 11#ifndef _LIBCPP_SRC_INCLUDE_TZDB_TZDB_LIST_PRIVATE_H12#define _LIBCPP_SRC_INCLUDE_TZDB_TZDB_LIST_PRIVATE_H13 14#include <__mutex/unique_lock.h>15#include <forward_list>16 17// When threads are not available the locking is not required.18// When threads are available, we use std::mutex over std::shared_mutex19// due to the increased overhead of std::shared_mutex.20// See shared_mutex_vs_mutex.bench.cpp21#if _LIBCPP_HAS_THREADS22#  include <mutex>23#endif24 25#include "types_private.h"26#include "tzdb_private.h"27 28_LIBCPP_BEGIN_NAMESPACE_STD29 30namespace chrono {31 32//===----------------------------------------------------------------------===//33//                          Private API34//===----------------------------------------------------------------------===//35 36// The tzdb_list stores a list of "tzdb" entries.37//38// The public tzdb database does not store the RULE entries of the IANA39// database. These entries are considered an implementation detail. Since most40// of the tzdb_list interface is exposed as "a list of tzdb entries" it's not41// possible to use a helper struct that stores a tzdb and the RULE database.42// Instead this class stores these in parallel forward lists.43//44// Since the nodes of a forward_list are stable it's possible to store pointers45// and references to these nodes.46class tzdb_list::__impl {47public:48  __impl() { __load_no_lock(); }49 50  [[nodiscard]] const tzdb& __load() {51#if _LIBCPP_HAS_THREADS52    unique_lock __lock{__mutex_};53#endif54    __load_no_lock();55    return __tzdb_.front();56  }57 58  using const_iterator = tzdb_list::const_iterator;59 60  const tzdb& __front() const noexcept {61#if _LIBCPP_HAS_THREADS62    unique_lock __lock{__mutex_};63#endif64    return __tzdb_.front();65  }66 67  const_iterator __erase_after(const_iterator __p) {68#if _LIBCPP_HAS_THREADS69    unique_lock __lock{__mutex_};70#endif71 72    __rules_.erase_after(std::next(__rules_.cbegin(), std::distance(__tzdb_.cbegin(), __p)));73    return __tzdb_.erase_after(__p);74  }75 76  const_iterator __begin() const noexcept {77#if _LIBCPP_HAS_THREADS78    unique_lock __lock{__mutex_};79#endif80    return __tzdb_.begin();81  }82  const_iterator __end() const noexcept {83    //  forward_list<T>::end does not access the list, so no need to take a lock.84    return __tzdb_.end();85  }86 87private:88  // Loads the tzdbs89  // pre: The caller ensures the locking, if needed, is done.90  void __load_no_lock() { chrono::__init_tzdb(__tzdb_.emplace_front(), __rules_.emplace_front()); }91 92#if _LIBCPP_HAS_THREADS93  mutable mutex __mutex_;94#endif95  forward_list<tzdb> __tzdb_;96 97  forward_list<__tz::__rules_storage_type> __rules_;98};99 100} // namespace chrono101 102_LIBCPP_END_NAMESPACE_STD103 104#endif // _LIBCPP_SRC_INCLUDE_TZDB_TZDB_LIST_PRIVATE_H105