Description
Proposal
Problem statement
It should be possible to convert a Thread
from/to a raw pointer for passing thread handles across API boundaries in an opaque manner.
Motivation, use-cases
Primary use case would be optimizing small futures executors. pollster
- a minimalistic futures executor with over 1 million downloads would be a direct beneficiary of this. Currently, pollster
needs to heap allocate a signal on every future being executed. Alternative would be to use a thread_local!
store of static signals/thread handles, but why bother, when a Thread
is already that?
As of today, Thread
is merely a newtype around opaque Arc, and I was able to abuse this knowledge to remove heap allocations from pollster and speed it up by up to 2x (zesterer/pollster#19). Thus, it would be trivial to add methods to convert the thread handle into a raw pointer, and go the other way around.
Additional use cases would be passing thread handles across FFI-boundary, which would enable better interoperability with other languages and dynamically loaded Rust libraries.
Solution sketches
We would add these functions to Thread
implementation:
#[must_use]
pub fn into_raw(self) -> *const () {
let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
Arc::into_raw(inner) as *const ()
}
pub unsafe fn from_raw(raw: *const ()) -> Thread {
Thread {
inner: Pin::new_unchecked(Arc::from_raw(raw as *const Inner))
}
}
Links and related work
Original PR to pollster
: zesterer/pollster#14
Prior implementation of this ACP: rust-lang/rust#97524
Implementation of this ACP (I closed it as duplicate): rust-lang/rust#109794