work with PIThreadPoolWorker

This commit is contained in:
2026-03-24 19:56:43 +03:00
parent 3102b985d5
commit 5868e0ec9d
3 changed files with 123 additions and 17 deletions

View File

@@ -42,23 +42,19 @@ PIThreadPoolWorker::PIThreadPoolWorker(int threads_count) {
PIThreadPoolWorker::~PIThreadPoolWorker() {
stop();
for (auto * w: workers) {
if (!w->thread.waitForFinish(1_s)) w->thread.terminate();
}
piDeleteAllAndClear(workers);
}
void PIThreadPoolWorker::start() {
for (auto w: workers)
for (auto w: workers) {
w->thread.start();
m_running = true;
w->notifier.notify();
}
}
void PIThreadPoolWorker::stop() {
m_running = false;
for (auto w: workers) {
w->thread.stop();
w->notifier.notify();
@@ -102,13 +98,87 @@ bool PIThreadPoolWorker::waitForFinish(PISystemTime timeout) {
}
bool PIThreadPoolWorker::isRunning() const {
return workers.every([](Worker * w) { return w->thread.isRunning(); });
}
bool PIThreadPoolWorker::waitForTasks(PISystemTime timeout) {
if (!isRunning()) return tasks_queue.getRef()->isEmpty();
auto checkWorking = [this] {
if (tasks_queue.getRef()->isNotEmpty()) return true;
for (auto * w: workers)
if (w->in_work > 0) return true;
return false;
};
if (timeout.isNull()) {
for (;;) {
if (!checkWorking()) break;
piMinSleep();
}
return true;
}
PITimeMeasurer tm;
while (tm.elapsed() < timeout) {
if (!checkWorking()) return true;
piMinSleep();
}
return tm.elapsed() < timeout;
}
bool PIThreadPoolWorker::waitForTask(int64_t id, PISystemTime timeout) {
if (!isRunning()) return tasks_queue.getRef()->every([id](const Task & t) { return t.id != id; });
auto checkWorking = [this, id] {
if (tasks_queue.getRef()->any([id](const Task & t) { return t.id == id; })) return true;
for (auto * w: workers)
if (w->in_work == id) return true;
return false;
};
if (timeout.isNull()) {
for (;;) {
if (!checkWorking()) break;
piMinSleep();
}
return true;
}
PITimeMeasurer tm;
while (tm.elapsed() < timeout) {
if (!checkWorking()) return true;
piMinSleep();
}
return tm.elapsed() < timeout;
}
void PIThreadPoolWorker::exec() {
start();
waitForStart();
waitForTasks();
stopAndWait();
}
int64_t PIThreadPoolWorker::enqueueTask(std::function<void(int64_t)> func, PIObject * context) {
if (context) {
if (!contexts[context]) {
contexts << context;
CONNECTL(context, deleted, ([this, context](PIObject *) {
contexts.remove(context);
auto qref = tasks_queue.getRef();
// auto prev_size = qref->size();
// piCout << "deleted" << (void *)context << qref->map<void *>([](const Task & t) { return t.context; });
qref->removeWhere([context](const Task & t) { return t.context == context; });
// piCout << prev_size << qref->size() << qref->map<void *>([](const Task & t) { return t.context; });
}));
}
}
int64_t id = ++next_task_id;
Task task;
task.id = id;
task.func = std::move(func);
task.context = context;
tasks_queue.getRef()->append(std::move(task));
tasks_queue.getRef()->enqueue(std::move(task));
for (auto * w: workers)
w->notifier.notify();
return id;
@@ -142,7 +212,6 @@ PIThreadPoolWorker::TaskStatus PIThreadPoolWorker::taskStatus(int64_t id) const
void PIThreadPoolWorker::threadFunc(Worker * w) {
w->notifier.wait();
if (w->thread.isStopping()) return;
if (!m_running) return;
Task task;
{
auto ref = tasks_queue.getRef();
@@ -151,7 +220,9 @@ void PIThreadPoolWorker::threadFunc(Worker * w) {
}
if (!task.isValid()) return;
w->in_work = task.id;
taskStarted(task.id);
task.func(task.id);
w->in_work = -1;
taskFinished(task.id);
w->notifier.notify();
}