test(quic): let the parked pool tasks leave before their flags go

ShouldSendWithoutBlockingQUIC parked every pool worker on tasks that
polled a release flag local to the block, and the block could end, the
flag with it, within the millisecond a task takes to notice the
release. The flags now live on the heap and the block waits for every
parked task to leave.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-11-01 02:32:12 +01:00
commit 12b15ceea2
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB

View file

@ -178,16 +178,23 @@ int main() {
// reader before the pool is parked.
WaitFor([&] { return readersStarted.load() > before; }, std::chrono::seconds(10));
std::atomic<bool> release = false;
std::atomic<unsigned> parked = 0;
// Leaked, and released only once every parked task has left, so
// none reads it after this block.
struct Parking {
std::atomic<bool> release = false;
std::atomic<unsigned> parked = 0;
std::atomic<unsigned> left = 0;
};
Parking& parking = *new Parking;
const unsigned workers = ThreadPool::activeThreads.load();
for (unsigned i = 0; i < workers * 2; ++i) {
ThreadPool::Enqueue([&] {
++parked;
while (!release.load()) std::this_thread::sleep_for(std::chrono::milliseconds(1));
ThreadPool::Enqueue([&parking] {
++parking.parked;
while (!parking.release.load()) std::this_thread::sleep_for(std::chrono::milliseconds(1));
++parking.left;
});
}
const bool allParked = WaitFor([&] { return parked.load() >= workers; }, std::chrono::seconds(10));
const bool allParked = WaitFor([&] { return parking.parked.load() >= workers; }, std::chrono::seconds(10));
constexpr int links = 100;
auto done = std::make_shared<std::atomic<int>>(0);
@ -208,7 +215,8 @@ int main() {
Check(allParked && finished && ok->load(),
std::format("with all {} pool workers parked, a chain of {} sends, each from the last one's onSent, completed",
workers, done->load()));
release = true;
parking.release = true;
WaitFor([&] { return parking.left.load() == workers * 2; }, std::chrono::seconds(10));
const bool arrived = WaitFor([&] { return received.Of('B').has_value(); }, std::chrono::seconds(10));
Check(arrived && FollowsPattern(*received.Of('B'), links), "and the peer read them all, in order");
*chain = nullptr;