From 68320629de4683c66cda1dc2da5e04e83d896ee7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 5 Apr 2024 20:36:11 +0300 Subject: [PATCH] ThreadPool stand-alone results --- src/files/WorldConverter.cpp | 6 +----- src/files/WorldConverter.h | 3 +-- src/graphics/render/ChunksRenderer.cpp | 1 + src/util/ThreadPool.h | 28 ++++++++++++++++++++------ 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/files/WorldConverter.cpp b/src/files/WorldConverter.cpp index 9588aad0..d64953aa 100644 --- a/src/files/WorldConverter.cpp +++ b/src/files/WorldConverter.cpp @@ -37,10 +37,6 @@ WorldConverter::~WorldConverter() { delete wfile; } -bool WorldConverter::hasNext() const { - return !tasks.empty(); -} - void WorldConverter::convertRegion(fs::path file) { int x, z; std::string name = file.stem().string(); @@ -72,7 +68,7 @@ void WorldConverter::convertPlayer(fs::path file) { } void WorldConverter::convertNext() { - if (!hasNext()) { + if (tasks.empty()) { throw std::runtime_error("no more regions to convert"); } convert_task task = tasks.front(); diff --git a/src/files/WorldConverter.h b/src/files/WorldConverter.h index 0a34a9e5..feabda2f 100644 --- a/src/files/WorldConverter.h +++ b/src/files/WorldConverter.h @@ -41,7 +41,6 @@ public: ); ~WorldConverter(); - bool hasNext() const; void convertNext(); void setOnComplete(runnable callback) { @@ -50,7 +49,7 @@ public: void update() override { convertNext(); - if (onComplete && !hasNext()) { + if (onComplete && tasks.empty()) { onComplete(); } } diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index eed947ec..de272a36 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -45,6 +45,7 @@ ChunksRenderer::ChunksRenderer( inwork.erase(mesh.key); }) { + threadPool.setStandaloneResults(false); renderer = std::make_unique( RENDERER_CAPACITY, level->content, cache, settings ); diff --git a/src/util/ThreadPool.h b/src/util/ThreadPool.h index 646e65a1..4f5bed77 100644 --- a/src/util/ThreadPool.h +++ b/src/util/ThreadPool.h @@ -46,6 +46,7 @@ class ThreadPool : public Task { std::atomic busyWorkers = 0; std::atomic jobsDone = 0; bool working = true; + bool standaloneResults = true; void threadLoop(int index, std::shared_ptr> worker) { std::condition_variable variable; @@ -71,10 +72,12 @@ class ThreadPool : public Task { { std::lock_guard lock(resultsMutex); results.push(ThreadPoolResult {variable, index, locked, result}); - locked = true; + if (!standaloneResults) { + locked = true; + } busyWorkers--; } - { + if (!standaloneResults){ std::unique_lock lock(mutex); variable.wait(lock, [&] { return !working || !locked; @@ -119,8 +122,10 @@ public: while (!results.empty()) { ThreadPoolResult entry = results.front(); results.pop(); - entry.locked = false; - entry.variable.notify_all(); + if (!standaloneResults) { + entry.locked = false; + entry.variable.notify_all(); + } } } @@ -138,8 +143,10 @@ public: resultConsumer(entry.entry); - entry.locked = false; - entry.variable.notify_all(); + if (!standaloneResults) { + entry.locked = false; + entry.variable.notify_all(); + } } if (onComplete && busyWorkers == 0) { @@ -158,10 +165,19 @@ public: jobsMutexCondition.notify_one(); } + /// @brief If false: worker will be blocked until it's result performed + void setStandaloneResults(bool flag) { + standaloneResults = flag; + } + + /// @brief onJobFailed called on exception thrown in worker thread. + /// Use engine.postRunnable when calling terminate() void setOnJobFailed(consumer callback) { this->onJobFailed = callback; } + /// @brief onComplete called in ThreadPool.update() when all jobs done + /// if ThreadPool was not terminated void setOnComplete(runnable callback) { this->onComplete = callback; }