mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00
runtime: handle missing context on wake (#6148)
This commit is contained in:
parent
49eb26f159
commit
2e5773a6fe
@ -178,7 +178,9 @@ cfg_rt! {
|
|||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub(super) fn with_scheduler<R>(f: impl FnOnce(Option<&scheduler::Context>) -> R) -> R {
|
pub(super) fn with_scheduler<R>(f: impl FnOnce(Option<&scheduler::Context>) -> R) -> R {
|
||||||
CONTEXT.with(|c| c.scheduler.with(f))
|
let mut f = Some(f);
|
||||||
|
CONTEXT.try_with(|c| c.scheduler.with(f.take().unwrap()))
|
||||||
|
.unwrap_or_else(|_| (f.take().unwrap())(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_taskdump! {
|
cfg_taskdump! {
|
||||||
|
@ -1366,4 +1366,66 @@ rt_test! {
|
|||||||
th.join().unwrap();
|
th.join().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(target_family = "wasm", ignore)]
|
||||||
|
fn wake_by_ref_from_thread_local() {
|
||||||
|
wake_from_thread_local(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(target_family = "wasm", ignore)]
|
||||||
|
fn wake_by_val_from_thread_local() {
|
||||||
|
wake_from_thread_local(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wake_from_thread_local(by_ref: bool) {
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::sync::mpsc::{channel, Sender};
|
||||||
|
use std::task::Waker;
|
||||||
|
|
||||||
|
struct TLData {
|
||||||
|
by_ref: bool,
|
||||||
|
waker: Option<Waker>,
|
||||||
|
done: Sender<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TLData {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if self.by_ref {
|
||||||
|
self.waker.take().unwrap().wake_by_ref();
|
||||||
|
} else {
|
||||||
|
self.waker.take().unwrap().wake();
|
||||||
|
}
|
||||||
|
let _ = self.done.send(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread_local! {
|
||||||
|
static TL_DATA: RefCell<Option<TLData>> = RefCell::new(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
let (send, recv) = channel();
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let rt = rt();
|
||||||
|
rt.block_on(rt.spawn(poll_fn(move |cx| {
|
||||||
|
let waker = cx.waker().clone();
|
||||||
|
let send = send.clone();
|
||||||
|
TL_DATA.with(|tl| {
|
||||||
|
tl.replace(Some(TLData {
|
||||||
|
by_ref,
|
||||||
|
waker: Some(waker),
|
||||||
|
done: send,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
Poll::Ready(())
|
||||||
|
})))
|
||||||
|
.unwrap();
|
||||||
|
})
|
||||||
|
.join()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(recv.recv().unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user