MapLibre Native Core
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
run_loop.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 #include <mbgl/actor/mailbox.hpp>
6 #include <mbgl/util/util.hpp>
9 
10 #include <atomic>
11 #include <functional>
12 #include <utility>
13 #include <queue>
14 #include <mutex>
15 
16 namespace mbgl {
17 namespace util {
18 
19 using LOOP_HANDLE = void *;
20 
21 class RunLoop : public Scheduler,
22  private util::noncopyable {
23 public:
24  enum class Type : uint8_t {
25  Default,
26  New,
27  };
28 
29  enum class Priority : bool {
30  Default = false,
31  High = true,
32  };
33 
34  enum class Event : uint8_t {
35  None = 0,
36  Read = 1,
37  Write = 2,
38  ReadWrite = Read | Write,
39  };
40 
42  ~RunLoop() override;
43 
44  static RunLoop* Get();
46 
47  void run();
48  void runOnce();
49  void stop();
50 
56  void setPlatformCallback(std::function<void()> callback) { platformCallback = std::move(callback); }
57 
58  // So far only needed by the libcurl backend.
59  void addWatch(int fd, Event, std::function<void(int, Event)>&& callback);
60  void removeWatch(int fd);
61 
62  // Invoke fn(args...) on this RunLoop.
63  template <class Fn, class... Args>
64  void invoke(Priority priority, Fn&& fn, Args&&... args) {
65  push(priority, WorkTask::make(std::forward<Fn>(fn), std::forward<Args>(args)...));
66  }
67 
68  // Invoke fn(args...) on this RunLoop.
69  template <class Fn, class... Args>
70  void invoke(Fn&& fn, Args&&... args) {
71  invoke(Priority::Default, std::forward<Fn>(fn), std::forward<Args>(args)...);
72  }
73 
74  // Post the cancellable work fn(args...) to this RunLoop.
75  template <class Fn, class... Args>
76  std::unique_ptr<AsyncRequest>
77  invokeCancellable(Fn&& fn, Args&&... args) {
78  std::shared_ptr<WorkTask> task = WorkTask::make(std::forward<Fn>(fn), std::forward<Args>(args)...);
79  push(Priority::Default, task);
80  return std::make_unique<WorkRequest>(task);
81  }
82 
83  void schedule(std::function<void()> fn) override { invoke(std::move(fn)); }
84  ::mapbox::base::WeakPtr<Scheduler> makeWeakPtr() override { return weakFactory.makeWeakPtr(); }
85 
86  class Impl;
87 
88 private:
90 
91  using Queue = std::queue<std::shared_ptr<WorkTask>>;
92 
93  // Wakes up the RunLoop so that it starts processing items in the queue.
94  void wake();
95 
96  // Adds a WorkTask to the queue, and wakes it up.
97  void push(Priority priority, std::shared_ptr<WorkTask> task) {
98  std::lock_guard<std::mutex> lock(mutex);
99  if (priority == Priority::High) {
100  highPriorityQueue.emplace(std::move(task));
101  } else {
102  defaultQueue.emplace(std::move(task));
103  }
104  wake();
105 
106  if (platformCallback) {
107  platformCallback();
108  }
109  }
110 
111  void process() {
112  std::shared_ptr<WorkTask> task;
113  std::unique_lock<std::mutex> lock(mutex);
114  while (true) {
115  if (!highPriorityQueue.empty()) {
116  task = std::move(highPriorityQueue.front());
117  highPriorityQueue.pop();
118  } else if (!defaultQueue.empty()) {
119  task = std::move(defaultQueue.front());
120  defaultQueue.pop();
121  } else {
122  break;
123  }
124  lock.unlock();
125  (*task)();
126  task.reset();
127  lock.lock();
128  }
129  }
130 
131  std::function<void()> platformCallback;
132 
133  Queue defaultQueue;
134  Queue highPriorityQueue;
135  std::mutex mutex;
136 
137  std::unique_ptr<Impl> impl;
138  ::mapbox::base::WeakPtrFactory<Scheduler> weakFactory{this};
139 };
140 
141 } // namespace util
142 } // namespace mbgl
143 
static std::shared_ptr< WorkTask > make(Fn &&, Args &&...)
std::unique_ptr< AsyncRequest > invokeCancellable(Fn &&fn, Args &&... args)
Definition: run_loop.hpp:77
void removeWatch(int fd)
::mapbox::base::WeakPtr< Scheduler > makeWeakPtr() override
Makes a weak pointer to this Scheduler.
Definition: run_loop.hpp:84
void invoke(Priority priority, Fn &&fn, Args &&... args)
Definition: run_loop.hpp:64
static RunLoop * Get()
static LOOP_HANDLE getLoopHandle()
void schedule(std::function< void()> fn) override
Enqueues a function for execution.
Definition: run_loop.hpp:83
RunLoop(Type type=Type::Default)
void invoke(Fn &&fn, Args &&... args)
Definition: run_loop.hpp:70
void setPlatformCallback(std::function< void()> callback)
Definition: run_loop.hpp:56
void addWatch(int fd, Event, std::function< void(int, Event)> &&callback)
void * LOOP_HANDLE
Definition: run_loop.hpp:19
Definition: actor.hpp:15
#define MBGL_STORE_THREAD(tid)
Definition: util.hpp:6