Currently, it's quite tedious to share code between synchronous and asynchronous implementations. For example, you have to use std::task::Waker in low-level asynchronous implementation, while you may opt for std::thread::park in synchronous one.
However, std::thread::Thread::unpark is quite similar to std::task::Waker, in fact, one can easily make a unpark waker from std::thread::Thread. But it requires to wrap the Thread in an Arc, while the internal implementation of Thread is already an Arc, so it's quite suboptimal.
That's why I suggest adding a method std::thread::Thread::park_waker(self) -> std::task::Waker.
It would for example allow using data structures like futures::task::AtomicWaker with thread parking, and factoring both synchronous and asynchronous implementation.
You may argue that data structures like AtomicWaker should be made generic instead, and that's a good point, but I'm still in favor of standardization through the Waker type.
It could also be implemented in a separate crate (I will maybe do this if my proposition is rejected), but I really think it should be in the standard library, as it's a std waker implementation for a std type.
(impl From<std::thread::Thread> for std::task::Waker could also be added)
Thank you for this interesting issue. In fact, I was not thinking about an executor use case, which must handle arbitrary user code; a warning should be written in park_waker documentation about interference with unexpectedunpark calls.
My use case, however, is completely different: a concurrent datastructure with blocking/asynchronosous operation; there cannot be any intereference because there is no unepected unpark.
It allows avoiding things like