Asynchronous GeometryTile deletion (#2051)
Co-authored-by: Tim Sylvester <tim@wetdogweather.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "run_loop_impl.hpp"
|
||||
|
||||
#include <mbgl/actor/scheduler.hpp>
|
||||
#include <mbgl/util/monotonic_timer.hpp>
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
@@ -90,6 +91,25 @@ void RunLoop::runOnce() {
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t RunLoop::waitForEmpty(std::chrono::milliseconds timeout) {
|
||||
const auto startTime = mbgl::util::MonotonicTimer::now();
|
||||
while (true) {
|
||||
std::size_t remaining;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
remaining = defaultQueue.size() + highPriorityQueue.size();
|
||||
}
|
||||
|
||||
const auto elapsed = mbgl::util::MonotonicTimer::now() - startTime;
|
||||
const auto elapsedMillis = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed);
|
||||
if (remaining == 0 || timeout <= elapsedMillis) {
|
||||
return remaining;
|
||||
}
|
||||
|
||||
runOnce();
|
||||
}
|
||||
}
|
||||
|
||||
void RunLoop::addWatch(int fd, Event event, std::function<void(int, Event)>&& cb) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ ThreadLocalBase::~ThreadLocalBase() {
|
||||
reinterpret_cast<StorageType&>(storage).~QThreadStorage();
|
||||
}
|
||||
|
||||
void* ThreadLocalBase::get() {
|
||||
return reinterpret_cast<StorageType&>(storage).localData()[0];
|
||||
void* ThreadLocalBase::get() const {
|
||||
return reinterpret_cast<const StorageType&>(storage).localData()[0];
|
||||
}
|
||||
|
||||
void ThreadLocalBase::set(void* ptr) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "scheduler.hpp"
|
||||
|
||||
#include <mbgl/util/monotonic_timer.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
|
||||
#include <cassert>
|
||||
@@ -12,7 +13,7 @@ Scheduler::~Scheduler() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
}
|
||||
|
||||
void Scheduler::schedule(std::function<void()> function) {
|
||||
void Scheduler::schedule(std::function<void()>&& function) {
|
||||
const std::lock_guard<std::mutex> lock(m_taskQueueMutex);
|
||||
m_taskQueue.push(std::move(function));
|
||||
|
||||
@@ -26,6 +27,7 @@ void Scheduler::processEvents() {
|
||||
{
|
||||
const std::unique_lock<std::mutex> lock(m_taskQueueMutex);
|
||||
std::swap(taskQueue, m_taskQueue);
|
||||
pendingItems += taskQueue.size();
|
||||
}
|
||||
|
||||
while (!taskQueue.empty()) {
|
||||
@@ -34,7 +36,29 @@ void Scheduler::processEvents() {
|
||||
function();
|
||||
}
|
||||
taskQueue.pop();
|
||||
pendingItems--;
|
||||
}
|
||||
|
||||
cvEmpty.notify_all();
|
||||
}
|
||||
|
||||
std::size_t Scheduler::waitForEmpty(std::chrono::milliseconds timeout) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
const auto startTime = mbgl::util::MonotonicTimer::now();
|
||||
std::unique_lock<std::mutex> lock(m_taskQueueMutex);
|
||||
const auto isDone = [&] {
|
||||
return m_taskQueue.empty() && pendingItems == 0;
|
||||
};
|
||||
while (!isDone()) {
|
||||
const auto elapsed = mbgl::util::MonotonicTimer::now() - startTime;
|
||||
if (timeout <= elapsed || !cvEmpty.wait_for(lock, timeout - elapsed, isDone)) {
|
||||
assert(isDone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_taskQueue.size() + pendingItems;
|
||||
}
|
||||
|
||||
} // namespace QMapLibre
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
@@ -19,7 +20,10 @@ public:
|
||||
~Scheduler() override;
|
||||
|
||||
// mbgl::Scheduler implementation.
|
||||
void schedule(std::function<void()> function) final;
|
||||
void schedule(std::function<void()>&& function) final;
|
||||
|
||||
std::size_t waitForEmpty(std::chrono::milliseconds timeout) override;
|
||||
|
||||
mapbox::base::WeakPtr<mbgl::Scheduler> makeWeakPtr() override { return weakFactory.makeWeakPtr(); }
|
||||
|
||||
void processEvents();
|
||||
@@ -31,6 +35,8 @@ private:
|
||||
MBGL_STORE_THREAD(tid);
|
||||
|
||||
std::mutex m_taskQueueMutex;
|
||||
std::condition_variable cvEmpty;
|
||||
std::atomic<std::size_t> pendingItems;
|
||||
std::queue<std::function<void()>> m_taskQueue;
|
||||
mapbox::base::WeakPtrFactory<Scheduler> weakFactory{this};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user