MapLibre Native Core
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
thread.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <mbgl/actor/actor.hpp>
4 #include <mbgl/actor/mailbox.hpp>
7 #include <mbgl/util/platform.hpp>
8 #include <mbgl/util/run_loop.hpp>
9 #include <mbgl/util/util.hpp>
10 
11 #include <cassert>
12 #include <future>
13 #include <memory>
14 #include <mutex>
15 #include <queue>
16 #include <string>
17 #include <thread>
18 #include <utility>
19 
20 namespace mbgl {
21 namespace util {
22 
39 template <typename Object>
40 class Thread {
41 public:
42  template <typename TupleArgs>
43  Thread(std::function<void()> prioritySetter_, const std::string& name, TupleArgs&& args) {
44  std::promise<void> running_;
45  running = running_.get_future();
46  thread = std::thread([this,
47  name,
48  capturedArgs = std::forward<TupleArgs>(args),
49  runningPromise = std::move(running_),
50  prioritySetter = std::move(prioritySetter_)]() mutable {
52  if (prioritySetter) prioritySetter();
54 
55  // narrowing the scope to release the Object before we detach the thread
56  {
58  loop = &loop_;
59  EstablishedActor<Object> establishedActor(loop_, object, std::move(capturedArgs));
60 
61  runningPromise.set_value();
62 
63  loop->run();
64 
65  (void) establishedActor;
66 
67  loop = nullptr;
68  }
69 
71  });
72  }
73 
74  template <typename... Args>
75  Thread(const std::string& name, Args&&... args)
76  : Thread([] { platform::makeThreadLowPriority(); }, name, std::make_tuple(std::forward<Args>(args)...)) {}
77 
78  template <typename... Args>
79  Thread(const std::function<void()>& prioritySetter, const std::string& name, Args&&... args)
80  : Thread(prioritySetter, name, std::make_tuple(std::forward<Args>(args)...)) {}
81 
82  ~Thread() {
83  if (paused) {
84  resume();
85  }
86 
87  std::promise<void> stoppable;
88 
89  running.wait();
90 
91  // Invoke a noop task on the run loop to ensure that we're executing
92  // run() before we call stop()
93  loop->invoke([&] {
94  stoppable.set_value();
95  });
96 
97  stoppable.get_future().get();
98 
99  loop->stop();
100  thread.join();
101  }
102 
108  return object.self();
109  }
110 
115  void pause() {
116  MBGL_VERIFY_THREAD(tid);
117 
118  assert(!paused);
119 
120  paused = std::make_unique<std::promise<void>>();
121  resumed = std::make_unique<std::promise<void>>();
122 
123  auto pausing = paused->get_future();
124 
125  running.wait();
126 
127  loop->invoke(RunLoop::Priority::High, [this] {
128  auto resuming = resumed->get_future();
129  paused->set_value();
130  resuming.get();
131  });
132 
133  pausing.get();
134  }
135 
136  // Resumes the `Object` thread previously paused by `pause()`.
137  void resume() {
138  MBGL_VERIFY_THREAD(tid);
139 
140  assert(paused);
141 
142  resumed->set_value();
143 
144  resumed.reset();
145  paused.reset();
146  }
147 
148 private:
149  MBGL_STORE_THREAD(tid);
150 
151  AspiringActor<Object> object;
152 
153  std::thread thread;
154 
155  std::future<void> running;
156 
157  std::unique_ptr<std::promise<void>> paused;
158  std::unique_ptr<std::promise<void>> resumed;
159 
160  util::RunLoop* loop = nullptr;
161 };
162 
166 std::function<void()> makeThreadPrioritySetter(std::string threadType);
167 
168 } // namespace util
169 } // namespace mbgl
void invoke(Priority priority, Fn &&fn, Args &&... args)
Definition: run_loop.hpp:64
Manages a thread with Object.
Definition: thread.hpp:40
Thread(const std::function< void()> &prioritySetter, const std::string &name, Args &&... args)
Definition: thread.hpp:79
Thread(const std::string &name, Args &&... args)
Definition: thread.hpp:75
ActorRef< std::decay_t< Object > > actor()
Definition: thread.hpp:107
Thread(std::function< void()> prioritySetter_, const std::string &name, TupleArgs &&args)
Definition: thread.hpp:43
void detachThread()
Called when a thread is destroyed.
void setCurrentThreadName(const std::string &name)
Set the name of the current thread, truncated at 15.
void makeThreadLowPriority()
Makes the current thread low priority.
void attachThread()
Called when a thread is created.
std::unique_ptr< Expression > string(std::unique_ptr< Expression >, std::unique_ptr< Expression > def=nullptr)
std::function< void()> makeThreadPrioritySetter(std::string threadType)
Definition: actor.hpp:15
Definition: tile_id.hpp:256
#define MBGL_VERIFY_THREAD(tid)
Definition: util.hpp:7