diff options
Diffstat (limited to 'include/mbgl/util/run_loop.hpp')
-rw-r--r-- | include/mbgl/util/run_loop.hpp | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/include/mbgl/util/run_loop.hpp b/include/mbgl/util/run_loop.hpp index acbea80273..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); } @@ -76,24 +86,42 @@ private: using Queue = std::queue<std::shared_ptr<WorkTask>>; - void push(std::shared_ptr<WorkTask>); + // Wakes up the RunLoop so that it starts processing items in the queue. + void wake(); - void withMutex(std::function<void()>&& fn) { + // Adds a WorkTask to the queue, and wakes it up. + void push(Priority priority, std::shared_ptr<WorkTask> task) { std::lock_guard<std::mutex> lock(mutex); - fn(); + if (priority == Priority::High) { + highPriorityQueue.emplace(std::move(task)); + } else { + defaultQueue.emplace(std::move(task)); + } + wake(); } void process() { - Queue queue_; - withMutex([&] { queue_.swap(queue); }); - - while (!queue_.empty()) { - (*(queue_.front()))(); - queue_.pop(); + std::shared_ptr<WorkTask> task; + 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; |