summary refs log tree commit diff
path: root/library/std/src/thread/mod.rs
diff options
context:
space:
mode:
authorJubilee <workingjubilee@gmail.com>2024-09-18 14:32:23 -0700
committerGitHub <noreply@github.com>2024-09-18 14:32:23 -0700
commit4722ad149e02f9923715fc69fc11af62af2c771f (patch)
tree9c661841b39f80f24ae1352900682ea2f9826032 /library/std/src/thread/mod.rs
parentf79a912d9edc3ad4db910c0e93672ed5c65133fa (diff)
parent0fa92b4159ae852c3ffdc25131518cc07ab21dd0 (diff)
downloadrust-4722ad149e02f9923715fc69fc11af62af2c771f.tar.gz
rust-4722ad149e02f9923715fc69fc11af62af2c771f.zip
Rollup merge of #97524 - ibraheemdev:thread-raw, r=ibraheemdev
Add `Thread::{into_raw, from_raw}`

Public API:
```rust
#![unstable(feature = "thread_raw", issue = "97523")]

impl Thread {
    pub fn into_raw(self) -> *const ();
    pub unsafe fn from_raw(ptr: *const ()) -> Thread;
}
```

ACP: https://github.com/rust-lang/libs-team/issues/200
Diffstat (limited to 'library/std/src/thread/mod.rs')
-rw-r--r--library/std/src/thread/mod.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 0fc63c5081b..33cb7e0bcca 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -1503,6 +1503,54 @@ impl Thread {
         self.inner.name.as_str()
     }
 
+    /// 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_cstr()
     }