- 
                Notifications
    
You must be signed in to change notification settings  - Fork 492
 
Open
Description
The following code reproduces cancellation deadlock. I understand the essence of the problem, if anyone is interested, I would be happy to discuss it. Also, I have studied the facebook/folly code, there is no such problem, since in-place executors are not allowed for stackless coroutines. It seems to me that this problem might be quite general. I did not find any mention of it in the std::execution proposal and in the P2175R0 paper, and do not fully understand how it deals with it.
#include "doctest/doctest.h"
#include <cppcoro/cancellation_registration.hpp>
#include <cppcoro/cancellation_source.hpp>
#include <cppcoro/single_consumer_event.hpp>
#include <cppcoro/static_thread_pool.hpp>
#include <cppcoro/sync_wait.hpp>
#include <cppcoro/task.hpp>
#include <cppcoro/when_all.hpp>
#include <chrono>
#include <thread>
TEST_SUITE_BEGIN("cancellation with events tests");
TEST_CASE("check deadlock freedom for events in cancellation callbacks")
{
	cppcoro::static_thread_pool threadPool(3);
	for (int i = 0; i < 20000; ++i)
	{
		cppcoro::single_consumer_event event1;
		cppcoro::single_consumer_event event2;
		cppcoro::cancellation_source source1;
		cppcoro::cancellation_source source2;
		auto coro1 = [&]() -> cppcoro::task<void> {
			auto guard =
				cppcoro::cancellation_registration(source1.token(), [&]() { event2.set(); });
			co_await event1;
		};
		auto coro2 = [&]() -> cppcoro::task<void> {
			auto guard =
				cppcoro::cancellation_registration(source2.token(), [&]() { event1.set(); });
			co_await event2;
		};
		auto cancelCoro1 = [&]() -> cppcoro::task<void> {
			co_await threadPool.schedule();
			source1.request_cancellation();
		};
		auto cancelCoro2 = [&]() -> cppcoro::task<void> {
			co_await threadPool.schedule();
			source2.request_cancellation();
		};
		auto fallbackCoro = [&]() -> cppcoro::task<void> {
			co_await threadPool.schedule();
			std::this_thread::sleep_for(std::chrono::microseconds(10));
			event1.set();
			event2.set();
		};
		cppcoro::sync_wait(
			cppcoro::when_all(coro1(), coro2(), cancelCoro1(), cancelCoro2(), fallbackCoro()));
	}
}
TEST_SUITE_END();
Metadata
Metadata
Assignees
Labels
No labels