1311128Sdim//===-- Timeout.h -----------------------------------------------*- C++ -*-===//
2311128Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6311128Sdim//
7311128Sdim//===----------------------------------------------------------------------===//
8311128Sdim
9311128Sdim#ifndef liblldb_Timeout_h_
10311128Sdim#define liblldb_Timeout_h_
11311128Sdim
12311128Sdim#include "llvm/ADT/Optional.h"
13321369Sdim#include "llvm/Support/Chrono.h"
14321369Sdim#include "llvm/Support/FormatProviders.h"
15311128Sdim
16311128Sdimnamespace lldb_private {
17311128Sdim
18311128Sdim// A general purpose class for representing timeouts for various APIs. It's
19311128Sdim// basically an llvm::Optional<std::chrono::duration<int64_t, Ratio>>, but we
20311128Sdim// customize it a bit to enable the standard chrono implicit conversions (e.g.
21311128Sdim// from Timeout<std::milli> to Timeout<std::micro>.
22311128Sdim//
23311128Sdim// The intended meaning of the values is:
24341825Sdim// - llvm::None - no timeout, the call should wait forever - 0 - poll, only
25341825Sdim// complete the call if it will not block - >0 - wait for a given number of
26341825Sdim// units for the result
27311128Sdimtemplate <typename Ratio>
28311128Sdimclass Timeout : public llvm::Optional<std::chrono::duration<int64_t, Ratio>> {
29311128Sdimprivate:
30311128Sdim  template <typename Ratio2> using Dur = std::chrono::duration<int64_t, Ratio2>;
31311128Sdim  template <typename Rep2, typename Ratio2>
32311128Sdim  using EnableIf = std::enable_if<
33311128Sdim      std::is_convertible<std::chrono::duration<Rep2, Ratio2>,
34311128Sdim                          std::chrono::duration<int64_t, Ratio>>::value>;
35311128Sdim
36311128Sdim  using Base = llvm::Optional<Dur<Ratio>>;
37311128Sdim
38311128Sdimpublic:
39311128Sdim  Timeout(llvm::NoneType none) : Base(none) {}
40311128Sdim  Timeout(const Timeout &other) = default;
41311128Sdim
42311128Sdim  template <typename Ratio2,
43311128Sdim            typename = typename EnableIf<int64_t, Ratio2>::type>
44311128Sdim  Timeout(const Timeout<Ratio2> &other)
45311128Sdim      : Base(other ? Base(Dur<Ratio>(*other)) : llvm::None) {}
46311128Sdim
47311128Sdim  template <typename Rep2, typename Ratio2,
48311128Sdim            typename = typename EnableIf<Rep2, Ratio2>::type>
49311128Sdim  Timeout(const std::chrono::duration<Rep2, Ratio2> &other)
50311128Sdim      : Base(Dur<Ratio>(other)) {}
51311128Sdim};
52311128Sdim
53311128Sdim} // namespace lldb_private
54311128Sdim
55321369Sdimnamespace llvm {
56321369Sdimtemplate<typename Ratio>
57321369Sdimstruct format_provider<lldb_private::Timeout<Ratio>, void> {
58321369Sdim  static void format(const lldb_private::Timeout<Ratio> &timeout,
59321369Sdim                     raw_ostream &OS, StringRef Options) {
60321369Sdim    typedef typename lldb_private::Timeout<Ratio>::value_type Dur;
61321369Sdim
62321369Sdim    if (!timeout)
63321369Sdim      OS << "<infinite>";
64321369Sdim    else
65321369Sdim      format_provider<Dur>::format(*timeout, OS, Options);
66321369Sdim  }
67321369Sdim};
68321369Sdim}
69321369Sdim
70311128Sdim#endif // liblldb_Timeout_h_
71