Skip to content

Commit e5781ae

Browse files
committed
fix cross thread cancel
1 parent d745b22 commit e5781ae

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

‎include/condy/runtime.hpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ class Runtime {
277277
tsan_release(&request);
278278
schedule_msg_ring_(curr_runtime,
279279
encode_work(&request, WorkType::Cancel));
280+
if (curr_runtime != nullptr) {
281+
// Ensure the cancel msg is submitted.
282+
curr_runtime->ring_.submit();
283+
curr_runtime->resume_work();
284+
}
280285
// Block until the runtime thread has submitted the cancel SQE. This is
281286
// important to prevent address reuse of the same data pointer, which
282287
// can lead to incorrect cancellation or other bugs.

‎tests/test_execution.cpp‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,31 @@ TEST_CASE("test execution - when_any") {
104104

105105
runtime.allow_exit();
106106
runtime_thread.join();
107+
}
108+
109+
TEST_CASE("test execution - when_any with different thread") {
110+
condy::Runtime runtime1, runtime2;
111+
std::thread thread1([&] { runtime1.run(); });
112+
std::thread thread2([&] { runtime2.run(); });
113+
114+
auto scheduler1 = condy::get_scheduler(runtime1);
115+
auto scheduler2 = condy::get_scheduler(runtime2);
116+
117+
__kernel_timespec ts = {
118+
.tv_sec = 60ll * 60ll,
119+
.tv_nsec = 0,
120+
};
121+
auto sender1 =
122+
ex::schedule(scheduler1) | ex::let_value([&] {
123+
return condy::detail::as_sender(condy::async_timeout(&ts, 0, 0));
124+
});
125+
auto sender2 = ex::schedule(scheduler2) | ex::then([] { return 42; });
126+
auto when_any_sender = exec::when_any(sender1, sender2);
127+
auto [r] = ex::sync_wait(when_any_sender).value();
128+
REQUIRE(r == 42);
129+
130+
runtime1.allow_exit();
131+
runtime2.allow_exit();
132+
thread1.join();
133+
thread2.join();
107134
}

0 commit comments

Comments
 (0)