add Thread::{into_raw, from_raw}

This commit is contained in:
Ibraheem Ahmed 2022-07-11 21:39:07 -04:00
parent 8a3325496f
commit 0fa92b4159

View File

@ -1230,6 +1230,54 @@ pub fn name(&self) -> Option<&str> {
self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
}
/// Consumes the `Thread`, returning a raw pointer.
///
/// To avoid a memory leak the pointer must be converted
/// back into a `Thread` using [`Thread::from_raw`].
///
/// # Examples
///
/// ```
/// #![feature(thread_raw)]
///
/// use std::thread::{self, Thread};
///
/// let thread = thread::current();
/// let id = thread.id();
/// let ptr = Thread::into_raw(thread);
/// unsafe {
/// assert_eq!(Thread::from_raw(ptr).id(), id);
/// }
/// ```
#[unstable(feature = "thread_raw", issue = "97523")]
pub fn into_raw(self) -> *const () {
// Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
Arc::into_raw(inner) as *const ()
}
/// Constructs a `Thread` from a raw pointer.
///
/// The raw pointer must have been previously returned
/// by a call to [`Thread::into_raw`].
///
/// # Safety
///
/// This function is unsafe because improper use may lead
/// to memory unsafety, even if the returned `Thread` is never
/// accessed.
///
/// Creating a `Thread` from a pointer other than one returned
/// from [`Thread::into_raw`] is **undefined behavior**.
///
/// Calling this function twice on the same raw pointer can lead
/// to a double-free if both `Thread` instances are dropped.
#[unstable(feature = "thread_raw", issue = "97523")]
pub unsafe fn from_raw(ptr: *const ()) -> Thread {
// Safety: Upheld by caller.
unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } }
}
fn cname(&self) -> Option<&CStr> {
self.inner.name.as_deref()
}