From 907b2a1993da644d6787766a9b5b674d7879ee98 Mon Sep 17 00:00:00 2001 From: emily Crandall Fleischman Date: Sat, 6 Jul 2024 17:18:48 -0400 Subject: [PATCH 1/2] Correct is_unique for Bytes from shared BytesMut The `is_unique` entry in the vtable for `Bytes` created from a shared `BytesMut` just called the `shared_is_unique` function from the `bytes` module. However, that function dereferences the `data` argument` as `bytes::Shared`, but the actual underlying type is `bytes_mut::Shared`. --- src/bytes_mut.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs index 282aaa710..2342077d2 100644 --- a/src/bytes_mut.rs +++ b/src/bytes_mut.rs @@ -1698,7 +1698,7 @@ unsafe fn rebuild_vec(ptr: *mut u8, mut len: usize, mut cap: usize, off: usize) static SHARED_VTABLE: Vtable = Vtable { clone: shared_v_clone, to_vec: shared_v_to_vec, - is_unique: crate::bytes::shared_is_unique, + is_unique: shared_v_is_unique, drop: shared_v_drop, }; @@ -1732,6 +1732,12 @@ unsafe fn shared_v_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> V } } +unsafe fn shared_v_is_unique(data: &AtomicPtr<()>) -> bool { + let shared = data.load(Ordering::Acquire); + let ref_count = (*shared.cast::()).ref_count.load(Ordering::Relaxed); + ref_count == 1 +} + unsafe fn shared_v_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) { data.with_mut(|shared| { release_shared(*shared as *mut Shared); From 4fe8b8226ae0031f0ea093a33b26c77ad429f740 Mon Sep 17 00:00:00 2001 From: emily Crandall Fleischman Date: Tue, 9 Jul 2024 17:19:40 -0400 Subject: [PATCH 2/2] add test --- tests/test_bytes.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 84c3d5a43..b2135905d 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -1172,3 +1172,12 @@ fn shared_is_unique() { drop(b); assert!(c.is_unique()); } + +#[test] +fn mut_shared_is_unique() { + let mut b = BytesMut::from(LONG); + let c = b.split().freeze(); + assert!(!c.is_unique()); + drop(b); + assert!(c.is_unique()); +}