summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-01-23 16:59:59 -0800
committerKonstantin Käfer <mail@kkaefer.com>2018-01-26 12:10:09 -0800
commit9bd5e4366e585b439186f1c1486a87dddba6bcbc (patch)
tree0a555f9b608e3f029ad5b8c0cf5d8d49461fbfb9
parentdee36ffdf539fcc6fe9a17a5b438208a380a5031 (diff)
downloadqtlocation-mapboxgl-upstream/prioritize-thread-pause-resume-2.tar.gz
[core] prioritize Thread::pause() callsupstream/prioritize-thread-pause-resume-2
-rw-r--r--include/mbgl/util/run_loop.hpp43
-rw-r--r--include/mbgl/util/thread.hpp2
2 files changed, 34 insertions, 11 deletions
diff --git a/include/mbgl/util/run_loop.hpp b/include/mbgl/util/run_loop.hpp
index 7167652687..381e3ae213 100644
--- a/include/mbgl/util/run_loop.hpp
+++ b/include/mbgl/util/run_loop.hpp
@@ -26,6 +26,11 @@ public:
New,
};
+ enum class Priority : bool {
+ Default = false,
+ High = true,
+ };
+
enum class Event : uint8_t {
None = 0,
Read = 1,
@@ -49,9 +54,14 @@ public:
// Invoke fn(args...) on this RunLoop.
template <class Fn, class... Args>
+ void invoke(Priority priority, Fn&& fn, Args&&... args) {
+ push(priority, WorkTask::make(std::forward<Fn>(fn), std::forward<Args>(args)...));
+ }
+
+ // Invoke fn(args...) on this RunLoop.
+ template <class Fn, class... Args>
void invoke(Fn&& fn, Args&&... args) {
- std::shared_ptr<WorkTask> task = WorkTask::make(std::forward<Fn>(fn), std::forward<Args>(args)...);
- push(task);
+ invoke(Priority::Default, std::forward<Fn>(fn), std::forward<Args>(args)...);
}
// Post the cancellable work fn(args...) to this RunLoop.
@@ -59,7 +69,7 @@ public:
std::unique_ptr<AsyncRequest>
invokeCancellable(Fn&& fn, Args&&... args) {
std::shared_ptr<WorkTask> task = WorkTask::make(std::forward<Fn>(fn), std::forward<Args>(args)...);
- push(task);
+ push(Priority::Default, task);
return std::make_unique<WorkRequest>(task);
}
@@ -80,25 +90,38 @@ private:
void wake();
// Adds a WorkTask to the queue, and wakes it up.
- void push(std::shared_ptr<WorkTask> task) {
+ void push(Priority priority, std::shared_ptr<WorkTask> task) {
std::lock_guard<std::mutex> lock(mutex);
- queue.push(std::move(task));
+ if (priority == Priority::High) {
+ highPriorityQueue.emplace(std::move(task));
+ } else {
+ defaultQueue.emplace(std::move(task));
+ }
wake();
}
void process() {
- std::unique_lock<std::mutex> lock(mutex);
std::shared_ptr<WorkTask> task;
- while (!queue.empty()) {
- task = std::move(queue.front());
- queue.pop();
+ std::unique_lock<std::mutex> lock(mutex);
+ while (true) {
+ if (!highPriorityQueue.empty()) {
+ task = std::move(highPriorityQueue.front());
+ highPriorityQueue.pop();
+ } else if (!defaultQueue.empty()) {
+ task = std::move(defaultQueue.front());
+ defaultQueue.pop();
+ } else {
+ break;
+ }
lock.unlock();
(*task)();
+ task.reset();
lock.lock();
}
}
- Queue queue;
+ Queue defaultQueue;
+ Queue highPriorityQueue;
std::mutex mutex;
std::unique_ptr<Impl> impl;
diff --git a/include/mbgl/util/thread.hpp b/include/mbgl/util/thread.hpp
index e3bd18143d..74e722b02d 100644
--- a/include/mbgl/util/thread.hpp
+++ b/include/mbgl/util/thread.hpp
@@ -103,7 +103,7 @@ public:
auto pausing = paused->get_future();
- loop->invoke([this] {
+ loop->invoke(RunLoop::Priority::High, [this] {
auto resuming = resumed->get_future();
paused->set_value();
resuming.get();