Skip to content

Commit c4fe01a

Browse files
committed
add Thread::{into_raw, from_raw}
1 parent 4861423 commit c4fe01a

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

std/src/thread/mod.rs

+48
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,54 @@ impl Thread {
12301230
self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
12311231
}
12321232

1233+
/// Consumes the `Thread`, returning a raw pointer.
1234+
///
1235+
/// To avoid a memory leak the pointer must be converted
1236+
/// back into a `Thread` using [`Thread::from_raw`].
1237+
///
1238+
/// # Examples
1239+
///
1240+
/// ```
1241+
/// #![feature(thread_raw)]
1242+
///
1243+
/// use std::thread::{self, Thread};
1244+
///
1245+
/// let thread = thread::current();
1246+
/// let id = thread.id();
1247+
/// let ptr = Thread::into_raw(thread);
1248+
/// unsafe {
1249+
/// assert_eq!(Thread::from_raw(ptr).id(), id);
1250+
/// }
1251+
/// ```
1252+
#[unstable(feature = "thread_raw", issue = "97523")]
1253+
pub fn into_raw(self) -> *const () {
1254+
// Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
1255+
let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
1256+
Arc::into_raw(inner) as *const ()
1257+
}
1258+
1259+
/// Constructs a `Thread` from a raw pointer.
1260+
///
1261+
/// The raw pointer must have been previously returned
1262+
/// by a call to [`Thread::into_raw`].
1263+
///
1264+
/// # Safety
1265+
///
1266+
/// This function is unsafe because improper use may lead
1267+
/// to memory unsafety, even if the returned `Thread` is never
1268+
/// accessed.
1269+
///
1270+
/// Creating a `Thread` from a pointer other than one returned
1271+
/// from [`Thread::into_raw`] is **undefined behavior**.
1272+
///
1273+
/// Calling this function twice on the same raw pointer can lead
1274+
/// to a double-free if both `Thread` instances are dropped.
1275+
#[unstable(feature = "thread_raw", issue = "97523")]
1276+
pub unsafe fn from_raw(ptr: *const ()) -> Thread {
1277+
// Safety: Upheld by caller.
1278+
unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } }
1279+
}
1280+
12331281
fn cname(&self) -> Option<&CStr> {
12341282
self.inner.name.as_deref()
12351283
}

0 commit comments

Comments
 (0)