aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Brad Dunbar <dunbarb2@gmail.com> 2024-04-08 11:05:04 -0400
committerGravatar GitHub <noreply@github.com> 2024-04-08 17:05:04 +0200
commit0d4cc7ffed2eadfb2028bade65b9ac0b6d231fc4 (patch)
tree82d737a90d9070d637440c43e52f4c3ffd6749b8
parentce8d8a0a029c0d296ade752ecc8c3e1ce9eee47f (diff)
downloadbytes-0d4cc7ffed2eadfb2028bade65b9ac0b6d231fc4.tar.gz
bytes-0d4cc7ffed2eadfb2028bade65b9ac0b6d231fc4.tar.zst
bytes-0d4cc7ffed2eadfb2028bade65b9ac0b6d231fc4.zip
Bytes: Use ManuallyDrop instead of mem::forget (#678)
-rw-r--r--src/bytes.rs20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/bytes.rs b/src/bytes.rs
index 0b443c8..4a0a94f 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -1,6 +1,7 @@
use core::iter::FromIterator;
+use core::mem::{self, ManuallyDrop};
use core::ops::{Deref, RangeBounds};
-use core::{cmp, fmt, hash, mem, ptr, slice, usize};
+use core::{cmp, fmt, hash, ptr, slice, usize};
use alloc::{
alloc::{dealloc, Layout},
@@ -828,13 +829,15 @@ impl From<&'static str> for Bytes {
}
impl From<Vec<u8>> for Bytes {
- fn from(mut vec: Vec<u8>) -> Bytes {
+ fn from(vec: Vec<u8>) -> Bytes {
+ let mut vec = ManuallyDrop::new(vec);
let ptr = vec.as_mut_ptr();
let len = vec.len();
let cap = vec.capacity();
// Avoid an extra allocation if possible.
if len == cap {
+ let vec = ManuallyDrop::into_inner(vec);
return Bytes::from(vec.into_boxed_slice());
}
@@ -843,7 +846,6 @@ impl From<Vec<u8>> for Bytes {
cap,
ref_cnt: AtomicUsize::new(1),
});
- mem::forget(vec);
let shared = Box::into_raw(shared);
// The pointer should be aligned, so this assert should
@@ -900,7 +902,7 @@ impl From<String> for Bytes {
impl From<Bytes> for Vec<u8> {
fn from(bytes: Bytes) -> Vec<u8> {
- let bytes = mem::ManuallyDrop::new(bytes);
+ let bytes = ManuallyDrop::new(bytes);
unsafe { (bytes.vtable.to_vec)(&bytes.data, bytes.ptr, bytes.len) }
}
}
@@ -1116,11 +1118,11 @@ unsafe fn shared_to_vec_impl(shared: *mut Shared, ptr: *const u8, len: usize) ->
.compare_exchange(1, 0, Ordering::AcqRel, Ordering::Relaxed)
.is_ok()
{
- let buf = (*shared).buf;
- let cap = (*shared).cap;
-
- // Deallocate Shared
- drop(Box::from_raw(shared as *mut mem::ManuallyDrop<Shared>));
+ // Deallocate the `Shared` instance without running its destructor.
+ let shared = *Box::from_raw(shared);
+ let shared = ManuallyDrop::new(shared);
+ let buf = shared.buf;
+ let cap = shared.cap;
// Copy back buffer
ptr::copy(ptr, buf, len);