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:
parent
328561fa91
commit
12b15ceea2
1 changed files with 15 additions and 7 deletions
|
|
@ -178,16 +178,23 @@ int main() {
|
|||
// reader before the pool is parked.
|
||||
WaitFor([&] { return readersStarted.load() > before; }, std::chrono::seconds(10));
|
||||
|
||||
// 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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue