Asynchronous GeometryTile deletion (#2051)

Co-authored-by: Tim Sylvester <tim@wetdogweather.com>
This commit is contained in:
mwilsnd
2024-02-28 17:18:08 -05:00
committed by GitHub
parent e3cbdb63a8
commit 4fff8a5d33
80 changed files with 1180 additions and 334 deletions

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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

View File

@@ -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};
};