修复webserver死锁

This commit is contained in:
2026-08-17 19:43:37 +08:00
parent 3881beea69
commit 47cf1af7a5
4 changed files with 326 additions and 4 deletions
+57 -1
View File
@@ -10,15 +10,21 @@
#include <algorithm>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <deque>
#include <exception>
#include <functional>
#include <mutex>
#include <optional>
#include <string>
#include <string_view>
#include <thread>
#include <type_traits>
#include <utility>
#include <vector>
namespace renderive::web {
namespace {
Gallery_View_Input gallery_input(const Event& event) {
@@ -133,6 +139,56 @@ trantor::EventLoop* automatic_render_loop() {
return thread.getLoop();
}
}
namespace detail {
class Automatic_Render_Executor final {
public:
Automatic_Render_Executor() {
const std::size_t worker_count = renderive::scheduling::scheduler_concurrency();
workers_.reserve(worker_count);
for (std::size_t index = 0; index < worker_count; ++index) {
workers_.emplace_back([this](std::stop_token stop) {
run(stop);
});
}
}
~Automatic_Render_Executor() {
for (auto& worker : workers_)
worker.request_stop();
condition_.notify_all();
}
void enqueue(std::function<void()> task) {
{
std::lock_guard lock(mutex_);
tasks_.push_back(std::move(task));
}
condition_.notify_one();
}
private:
void run(std::stop_token stop) {
for (;;) {
std::function<void()> task;
{
std::unique_lock lock(mutex_);
if (!condition_.wait(lock, stop, [this] {
return !tasks_.empty();
}))
return;
task = std::move(tasks_.front());
tasks_.pop_front();
}
task();
}
}
std::mutex mutex_;
std::condition_variable_any condition_;
std::deque<std::function<void()>> tasks_;
std::vector<std::jthread> workers_;
};
Automatic_Render_Executor& automatic_render_executor() {
static Automatic_Render_Executor executor;
return executor;
}
}
struct Gallery_Plot_Session::Impl : std::enable_shared_from_this<Gallery_Plot_Session::Impl> {
using Clock = std::chrono::steady_clock;
explicit Impl(bool enable_automatic_low_latency)
@@ -247,7 +303,7 @@ struct Gallery_Plot_Session::Impl : std::enable_shared_from_this<Gallery_Plot_Se
}
auto self = shared_from_this();
try {
renderive::scheduling::enqueue_task([self = std::move(self), generation] {
detail::automatic_render_executor().enqueue([self = std::move(self), generation] {
self->run_automatic_render(generation);
});
} catch (...) {