Closed quininer closed 18 hours ago
That's unfortunate, tokio::task::yield_now()
registers the waker to the defer list.
I wonder if there is a way to clear the Tokio thread context for a specific scope.
This isn't a solution, but it might be a good idea to avoid using tokio::task::yield_now()
within another executor (in scenarios where Tokio context exists) for now.
avoid using tokio::task::yield_now() within another executor (in scenarios where Tokio context exists) for now.
This is almost impossible and unreasonable because yield_now
may appear in third-party dependencies.
make block_in_place
clear the scheduler
context is the simplest solution I can think of.
The real problem here is that context passed using thread_local
does not reflect current executor. maybe access the tokio context through waker vtable and data is a better approach.
#[track_caller]
pub(crate) fn defer(waker: &Waker) {
if ptr::eq(waker.vtable(), WAKER_VTABLE_REF) {
unsafe {
let ctx = waker.data().cast::<TokioWaker>().as_ref();
ctx.scheduler.defer(waker);
}
} else {
// Called from outside of the runtime, immediately wake the
// task.
waker.wake_by_ref();
}
}
That might be a good solution, but it might take some time as .vtable()
added recently (1.83
)
Another approach could involve having Tokio remove the defer list from the caller's side. This might require some internal code changes, so I don’t think it’s something that would happen anytime soon.
Using an external executor's block_on
within Tokio requires use of block_in_place
.
That said, you say that it doesn't work even with block_in_place
? If so, then that sounds like a bug.
Version
Platform
Description
when
yield_now().await
is called in an external executorblock_on
, the wakeup maybe lost due to enter defer logic.I tried this code:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c12f5f957e5a1d33c4184d52b07e40b5
I also tried
block_on
withblock_in_place
, but this still results in lost wakeups becauseblock_in_place
only exitsruntime
but notscheduler
.https://github.com/tokio-rs/tokio/blob/tokio-1.41.1/tokio/src/runtime/context/runtime_mt.rs#L29 https://github.com/tokio-rs/tokio/blob/tokio-1.41.1/tokio/src/runtime/context.rs#L184
I expected to see this happen: print
start
anddone
.Instead, this happened: prints
start
and then hangs.