1061da546Spatrick //===-- Timeout.h -----------------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_UTILITY_TIMEOUT_H 10dda28197Spatrick #define LLDB_UTILITY_TIMEOUT_H 11061da546Spatrick 12061da546Spatrick #include "llvm/Support/Chrono.h" 13061da546Spatrick #include "llvm/Support/FormatProviders.h" 14*f6aab3d8Srobert #include <optional> 15061da546Spatrick 16061da546Spatrick namespace lldb_private { 17061da546Spatrick 18061da546Spatrick // A general purpose class for representing timeouts for various APIs. It's 19*f6aab3d8Srobert // basically an std::optional<std::chrono::duration<int64_t, Ratio>>, but we 20061da546Spatrick // customize it a bit to enable the standard chrono implicit conversions (e.g. 21061da546Spatrick // from Timeout<std::milli> to Timeout<std::micro>. 22061da546Spatrick // 23061da546Spatrick // The intended meaning of the values is: 24*f6aab3d8Srobert // - std::nullopt - no timeout, the call should wait forever - 0 - poll, only 25061da546Spatrick // complete the call if it will not block - >0 - wait for a given number of 26061da546Spatrick // units for the result 27061da546Spatrick template <typename Ratio> 28*f6aab3d8Srobert class Timeout : public std::optional<std::chrono::duration<int64_t, Ratio>> { 29061da546Spatrick private: 30061da546Spatrick template <typename Ratio2> using Dur = std::chrono::duration<int64_t, Ratio2>; 31061da546Spatrick template <typename Rep2, typename Ratio2> 32061da546Spatrick using EnableIf = std::enable_if< 33061da546Spatrick std::is_convertible<std::chrono::duration<Rep2, Ratio2>, 34061da546Spatrick std::chrono::duration<int64_t, Ratio>>::value>; 35061da546Spatrick 36*f6aab3d8Srobert using Base = std::optional<Dur<Ratio>>; 37061da546Spatrick 38061da546Spatrick public: Timeout(std::nullopt_t none)39*f6aab3d8Srobert Timeout(std::nullopt_t none) : Base(none) {} 40061da546Spatrick 41061da546Spatrick template <typename Ratio2, 42061da546Spatrick typename = typename EnableIf<int64_t, Ratio2>::type> Timeout(const Timeout<Ratio2> & other)43061da546Spatrick Timeout(const Timeout<Ratio2> &other) 44*f6aab3d8Srobert : Base(other ? Base(Dur<Ratio>(*other)) : std::nullopt) {} 45061da546Spatrick 46061da546Spatrick template <typename Rep2, typename Ratio2, 47061da546Spatrick typename = typename EnableIf<Rep2, Ratio2>::type> Timeout(const std::chrono::duration<Rep2,Ratio2> & other)48061da546Spatrick Timeout(const std::chrono::duration<Rep2, Ratio2> &other) 49061da546Spatrick : Base(Dur<Ratio>(other)) {} 50061da546Spatrick }; 51061da546Spatrick 52061da546Spatrick } // namespace lldb_private 53061da546Spatrick 54061da546Spatrick namespace llvm { 55061da546Spatrick template<typename Ratio> 56061da546Spatrick struct format_provider<lldb_private::Timeout<Ratio>, void> { 57061da546Spatrick static void format(const lldb_private::Timeout<Ratio> &timeout, 58061da546Spatrick raw_ostream &OS, StringRef Options) { 59061da546Spatrick typedef typename lldb_private::Timeout<Ratio>::value_type Dur; 60061da546Spatrick 61061da546Spatrick if (!timeout) 62061da546Spatrick OS << "<infinite>"; 63061da546Spatrick else 64061da546Spatrick format_provider<Dur>::format(*timeout, OS, Options); 65061da546Spatrick } 66061da546Spatrick }; 67061da546Spatrick } 68061da546Spatrick 69dda28197Spatrick #endif // LLDB_UTILITY_TIMEOUT_H 70