Tracking Issue for `waker_getters` · Issue #96992 · rust-lang/rust · GitHub as well as Stabilize `waker_getters` by kevinmehall · Pull Request #129919 · rust-lang/rust · GitHub have been merged today.
It allows notably to retrieve the vtable of a Waker
, and that can be used for example to match on it and identify the current async runtime, as presented in this comment.
When I implemented asynchronous support in PyO3, I was also needing this feature (and I had to use a dirty hack based on TLS while waiting for it).
However, to avoid useless unsafe code, I'm using the Wake
trait to craft my coroutine runtime Waker
, and there's the rub... I cannot use waker_getters
feature because I don't have access to the vtable of the wakers derived from Arc<W> where W: Wake
. The waker_getters
feature is quite unusable with Arc<W> where W: Wake
.
I tried two times (here and here) to highlight this problem in the issue, proposing two different ways of making the feature compatible with the Wake
trait, but my attempts were kind of ignored. So I make a new attempt here.
A possible solution to the problem could be this implementation:
impl<W: Wake + Send + Sync + 'static> Arc<W> {
const fn waker_vtable() -> &'static RawWakerVTable { /*...*/ }
}
It could also be done with an extension trait, something like:
pub trait WakeExt: Wake + Send + Sync + 'static {
/// Vtable of waker derived from `Arc<Self>`.
fn waker_vtable() -> &'static RawWakerVTable { /*...*/ }
fn try_from_waker(waker: Waker) -> Result<Arc<Self>, Waker> { /*...*/ }
fn try_from_waker_ref(waker: &Waker) -> Result<&Self, &Waker> { /*...*/ }
}
impl<W: Wake + Send + Sync + 'static> WakeExt for W {}