Skip to content

Commit 6b4b0ed

Browse files
authored
Fix Bytes::is_unique when created from shared BytesMut (#718)
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`.
1 parent ce8d8a0 commit 6b4b0ed

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/bytes_mut.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1698,7 +1698,7 @@ unsafe fn rebuild_vec(ptr: *mut u8, mut len: usize, mut cap: usize, off: usize)
16981698
static SHARED_VTABLE: Vtable = Vtable {
16991699
clone: shared_v_clone,
17001700
to_vec: shared_v_to_vec,
1701-
is_unique: crate::bytes::shared_is_unique,
1701+
is_unique: shared_v_is_unique,
17021702
drop: shared_v_drop,
17031703
};
17041704

@@ -1732,6 +1732,12 @@ unsafe fn shared_v_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> V
17321732
}
17331733
}
17341734

1735+
unsafe fn shared_v_is_unique(data: &AtomicPtr<()>) -> bool {
1736+
let shared = data.load(Ordering::Acquire);
1737+
let ref_count = (*shared.cast::<Shared>()).ref_count.load(Ordering::Relaxed);
1738+
ref_count == 1
1739+
}
1740+
17351741
unsafe fn shared_v_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
17361742
data.with_mut(|shared| {
17371743
release_shared(*shared as *mut Shared);

tests/test_bytes.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,3 +1172,12 @@ fn shared_is_unique() {
11721172
drop(b);
11731173
assert!(c.is_unique());
11741174
}
1175+
1176+
#[test]
1177+
fn mut_shared_is_unique() {
1178+
let mut b = BytesMut::from(LONG);
1179+
let c = b.split().freeze();
1180+
assert!(!c.is_unique());
1181+
drop(b);
1182+
assert!(c.is_unique());
1183+
}

0 commit comments

Comments
 (0)