add Thread::{into_raw, from_raw}
This commit is contained in:
parent
8a3325496f
commit
0fa92b4159
@ -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()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user