1 //===-- Timeout.h -----------------------------------------------*- C++ -*-===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_UTILITY_TIMEOUT_H 10 #define LLDB_UTILITY_TIMEOUT_H 11 12 #include "llvm/Support/Chrono.h" 13 #include "llvm/Support/FormatProviders.h" 14 #include <optional> 15 16 namespace lldb_private { 17 18 // A general purpose class for representing timeouts for various APIs. It's 19 // basically an std::optional<std::chrono::duration<int64_t, Ratio>>, but we 20 // customize it a bit to enable the standard chrono implicit conversions (e.g. 21 // from Timeout<std::milli> to Timeout<std::micro>. 22 // 23 // The intended meaning of the values is: 24 // - std::nullopt - no timeout, the call should wait forever - 0 - poll, only 25 // complete the call if it will not block - >0 - wait for a given number of 26 // units for the result 27 template <typename Ratio> 28 class Timeout : public std::optional<std::chrono::duration<int64_t, Ratio>> { 29 private: 30 template <typename Ratio2> using Dur = std::chrono::duration<int64_t, Ratio2>; 31 template <typename Rep2, typename Ratio2> 32 using EnableIf = std::enable_if< 33 std::is_convertible<std::chrono::duration<Rep2, Ratio2>, 34 std::chrono::duration<int64_t, Ratio>>::value>; 35 36 using Base = std::optional<Dur<Ratio>>; 37 38 public: Timeout(std::nullopt_t none)39 Timeout(std::nullopt_t none) : Base(none) {} 40 41 template <typename Ratio2, 42 typename = typename EnableIf<int64_t, Ratio2>::type> Timeout(const Timeout<Ratio2> & other)43 Timeout(const Timeout<Ratio2> &other) 44 : Base(other ? Base(Dur<Ratio>(*other)) : std::nullopt) {} 45 46 template <typename Rep2, typename Ratio2, 47 typename = typename EnableIf<Rep2, Ratio2>::type> Timeout(const std::chrono::duration<Rep2,Ratio2> & other)48 Timeout(const std::chrono::duration<Rep2, Ratio2> &other) 49 : Base(Dur<Ratio>(other)) {} 50 }; 51 52 } // namespace lldb_private 53 54 namespace llvm { 55 template<typename Ratio> 56 struct format_provider<lldb_private::Timeout<Ratio>, void> { 57 static void format(const lldb_private::Timeout<Ratio> &timeout, 58 raw_ostream &OS, StringRef Options) { 59 typedef typename lldb_private::Timeout<Ratio>::value_type Dur; 60 61 if (!timeout) 62 OS << "<infinite>"; 63 else 64 format_provider<Dur>::format(*timeout, OS, Options); 65 } 66 }; 67 } 68 69 #endif // LLDB_UTILITY_TIMEOUT_H 70