pstore2
heartbeat.hpp
Go to the documentation of this file.
1 //===- lib/core/heartbeat.hpp -----------------------------*- mode: C++ -*-===//
2 //* _ _ _ _ *
3 //* | |__ ___ __ _ _ __| |_| |__ ___ __ _| |_ *
4 //* | '_ \ / _ \/ _` | '__| __| '_ \ / _ \/ _` | __| *
5 //* | | | | __/ (_| | | | |_| |_) | __/ (_| | |_ *
6 //* |_| |_|\___|\__,_|_| \__|_.__/ \___|\__,_|\__| *
7 //* *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
18 
19 #ifndef PSTORE_CORE_HEARTBEAT_HPP
20 #define PSTORE_CORE_HEARTBEAT_HPP
21 
22 #include <atomic>
23 #include <chrono>
24 #include <condition_variable>
25 #include <functional>
26 #include <memory>
27 #include <mutex>
28 #include <thread>
29 #include <unordered_map>
30 
31 namespace pstore {
32 
33  class heartbeat {
34  public:
35  static std::shared_ptr<heartbeat> get ();
36 
37  ~heartbeat ();
38 
39  heartbeat (heartbeat const &) = delete;
40  heartbeat & operator= (heartbeat const &) = delete;
41 
47  using key_type = std::uintptr_t;
48 
50  template <typename T>
51  static key_type to_key_type (T * t) {
52  static_assert (sizeof (key_type) <= sizeof (t), "heartbeat::key_type is too small");
53  return reinterpret_cast<key_type> (t);
54  }
55 
56  using callback = std::function<void (key_type)>;
57  void attach (key_type key, callback cb);
58  void detach (key_type key);
59 
61  void stop ();
62 
64  class worker_thread {
65  public:
66  worker_thread ();
67  worker_thread (worker_thread const &) = delete;
68  worker_thread (worker_thread &&) = delete;
69 
70  ~worker_thread () = default;
71 
72  worker_thread & operator= (worker_thread const &) = delete;
73  worker_thread & operator= (worker_thread &&) = delete;
74 
75  void attach (heartbeat::key_type key, callback cb);
76  void detach (heartbeat::key_type key);
77 
79  void run () noexcept;
80 
85  void step () const;
86 
89  void stop () noexcept;
90 
91  private:
92  using duration_type = std::chrono::milliseconds;
94  static duration_type const delay_time_;
97  static duration_type const max_time_;
98 
103  duration_type const * sleep_time_;
104 
106  bool done_ = false;
107 
110  std::mutex mut_;
112  std::condition_variable cv_;
113 
116  std::unordered_map<heartbeat::key_type, heartbeat::callback> callbacks_;
117  };
118 
119  private:
122  heartbeat () noexcept = default;
123 
124  struct state {
125  worker_thread worker;
126  std::thread thread;
127  };
128  std::unique_ptr<state> state_;
129  };
130 
131 } // end namespace pstore
132 
133 #endif // PSTORE_CORE_HEARTBEAT_HPP
void stop()
Stops the heartbeat thread.
Definition: heartbeat.hpp:64
static key_type to_key_type(T *t)
A small convenience function which will convert a pointer to key_type.
Definition: heartbeat.hpp:51
void stop() noexcept
Instructs the worker thread to exit on its next iteration.
Definition: heartbeat.cpp:77
void step() const
Executes a single invocation of each of the attached callbacks.
Definition: heartbeat.cpp:56
Definition: heartbeat.hpp:33
Definition: nonpod2.cpp:40
void run() noexcept
This is the thread entry point.
Definition: heartbeat.cpp:62
std::uintptr_t key_type
A key_type value is used to distinguish between different callbacks that are attached to the heartbea...
Definition: heartbeat.hpp:47