43 lines
1.4 KiB
C++
43 lines
1.4 KiB
C++
|
|
//SPDX-License-Identifier: LGPL-3.0-only
|
||
|
|
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||
|
|
|
||
|
|
// ThreadPool::Stop ends the pool for everyone in it, the thread that joined
|
||
|
|
// it with JoinPool too. Stop woke and joined the worker threads only, so a
|
||
|
|
// JoinPool caller slept on, never told. And Stop called again joined threads
|
||
|
|
// already joined, which throws.
|
||
|
|
//
|
||
|
|
// Here another thread stops the pool this one has joined, then stops it
|
||
|
|
// again. A watchdog fails the test if JoinPool doesn't return.
|
||
|
|
|
||
|
|
#include <cstdlib>
|
||
|
|
#include <unistd.h>
|
||
|
|
|
||
|
|
import Crafter.Thread;
|
||
|
|
import std;
|
||
|
|
|
||
|
|
using namespace Crafter;
|
||
|
|
using namespace std::chrono_literals;
|
||
|
|
|
||
|
|
int main() {
|
||
|
|
std::thread watchdog([] {
|
||
|
|
std::this_thread::sleep_for(10s);
|
||
|
|
std::println("FAIL JoinPool didn't return within 10 s of Stop");
|
||
|
|
_exit(EXIT_FAILURE);
|
||
|
|
});
|
||
|
|
watchdog.detach();
|
||
|
|
|
||
|
|
ThreadPool::Start(4);
|
||
|
|
std::atomic<int> ran = 0;
|
||
|
|
for (int i = 0; i < 100; ++i) ThreadPool::Enqueue([&ran] { ++ran; });
|
||
|
|
std::thread stopper([] {
|
||
|
|
std::this_thread::sleep_for(100ms);
|
||
|
|
ThreadPool::Stop();
|
||
|
|
});
|
||
|
|
ThreadPool::JoinPool();
|
||
|
|
stopper.join();
|
||
|
|
std::println("{} Stop from another thread ends the JoinPool of the thread that joined, after the queued tasks ({} of 100)",
|
||
|
|
ran == 100 ? "PASS" : "FAIL", ran.load());
|
||
|
|
ThreadPool::Stop();
|
||
|
|
std::println("PASS and stopping it again does nothing");
|
||
|
|
return ran == 100 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||
|
|
}
|