about summary refs log tree commit diff
path: root/library/alloc/src/sync
diff options
context:
space:
mode:
authorFrank Steffahn <frank.steffahn@stu.uni-kiel.de>2020-08-25 17:30:46 +0200
committerFrank Steffahn <fdsteffahn@gmail.com>2023-01-22 01:43:25 +0900
commit33696fa9cab5bec947147d65833233b957b5edd5 (patch)
treef6d8b041c24bdacc852b0a6864173bb388cae8b1 /library/alloc/src/sync
parent44a500c8c187b245638684748f54bd6ec67e0b25 (diff)
downloadrust-33696fa9cab5bec947147d65833233b957b5edd5.tar.gz
rust-33696fa9cab5bec947147d65833233b957b5edd5.zip
Add Arc::into_inner for safely discarding Arcs without calling the destructor on the inner type.
Mainly rebased and squashed from PR rust-lang/rust#79665,
furthermore includes minor changes in comments.
Diffstat (limited to 'library/alloc/src/sync')
-rw-r--r--library/alloc/src/sync/tests.rs32
1 files changed, 32 insertions, 0 deletions
diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs
index 0fae8953aa2..863d58bdf4d 100644
--- a/library/alloc/src/sync/tests.rs
+++ b/library/alloc/src/sync/tests.rs
@@ -102,6 +102,38 @@ fn try_unwrap() {
 }
 
 #[test]
+fn into_inner() {
+    for _ in 0..100
+    // ^ Increase chances of hitting potential race conditions
+    {
+        let x = Arc::new(3);
+        let y = Arc::clone(&x);
+        let r_thread = std::thread::spawn(|| Arc::into_inner(x));
+        let s_thread = std::thread::spawn(|| Arc::into_inner(y));
+        let r = r_thread.join().expect("r_thread panicked");
+        let s = s_thread.join().expect("s_thread panicked");
+        assert!(
+            matches!((r, s), (None, Some(3)) | (Some(3), None)),
+            "assertion failed: unexpected result `{:?}`\
+            \n  expected `(None, Some(3))` or `(Some(3), None)`",
+            (r, s),
+        );
+    }
+
+    let x = Arc::new(3);
+    assert_eq!(Arc::into_inner(x), Some(3));
+
+    let x = Arc::new(4);
+    let y = Arc::clone(&x);
+    assert_eq!(Arc::into_inner(x), None);
+    assert_eq!(Arc::into_inner(y), Some(4));
+
+    let x = Arc::new(5);
+    let _w = Arc::downgrade(&x);
+    assert_eq!(Arc::into_inner(x), Some(5));
+}
+
+#[test]
 fn into_from_raw() {
     let x = Arc::new(Box::new("hello"));
     let y = x.clone();