Files
msime-windows/server/src/settings/serial_task_queue.h
T
Evan 42238a2af6 style: 用 .clang-format 重排 server / windows / ui / log
一次性重排,无任何行为改动。四个目录各自的 .clang-format 放在仓库里已久,但全组织只有
MSIME-Linux 在 CI 里执行 clang-format 检查,这边 149 个文件里有 149 个不符合自己声明的风格。

已逐文件核对语义等价:去掉空白、注释与相邻字符串字面量拆分之后,全部 149 个文件与重排前逐字节
相同。差异只有三类——缩进与换行、clang-format 补的 } // namespace 结尾注释、以及长字符串被拆成
相邻字面量(C++ 保证自动拼接)。

这个提交会写进 .git-blame-ignore-revs。
2026-09-06 12:13:47 +09:00

105 lines
2.7 KiB
C++

#pragma once
#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <thread>
#include <utility>
// Work runs serially on one worker. Completions are explicitly drained by the
// owner thread. Stop drains accepted work; no detached threads outlive the owner.
class SerialTaskQueue
{
public:
using Completion = std::function<void()>;
using Task = std::function<Completion()>;
SerialTaskQueue(Completion notify, Completion error, Completion cleanup = {})
: notify_(std::move(notify)), error_(std::move(error)), cleanup_(std::move(cleanup)), thread_([this] { Run(); })
{
}
~SerialTaskQueue()
{
Stop();
thread_.join();
}
bool Submit(Task task)
{
std::lock_guard<std::mutex> lock(mutex_);
if (stopping_)
return false;
tasks_.push_back(std::move(task));
ready_.notify_one();
return true;
}
void Stop()
{
std::lock_guard<std::mutex> lock(mutex_);
stopping_ = true;
ready_.notify_one();
}
bool Stopped()
{
std::lock_guard<std::mutex> lock(mutex_);
return stopped_;
}
void Drain(bool deliver = true)
{
std::deque<Completion> completed;
{
std::lock_guard<std::mutex> lock(mutex_);
completed.swap(completed_);
}
if (deliver)
for (auto &completion : completed)
completion();
}
private:
void Run()
{
for (;;)
{
Task task;
{
std::unique_lock<std::mutex> lock(mutex_);
ready_.wait(lock, [this] { return stopping_ || !tasks_.empty(); });
if (tasks_.empty())
break;
task = std::move(tasks_.front());
tasks_.pop_front();
}
Completion result;
try
{
result = task();
}
catch (...)
{
result = error_;
}
if (result)
{
{
std::lock_guard<std::mutex> lock(mutex_);
completed_.push_back(std::move(result));
}
notify_();
}
}
if (cleanup_)
cleanup_();
{
std::lock_guard<std::mutex> lock(mutex_);
stopped_ = true;
}
notify_();
}
Completion notify_, error_, cleanup_;
std::mutex mutex_;
std::condition_variable ready_;
std::deque<Task> tasks_;
std::deque<Completion> completed_;
bool stopping_ = false, stopped_ = false;
std::thread thread_;
};