xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Utility/Timeout.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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