This commit is contained in:
Matthias Schiffer 2019-08-09 22:41:26 +02:00
parent 709f755da6
commit 9aae18d764
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C

View file

@ -2,8 +2,6 @@ use super::posix;
use core::{mem, ptr, slice}; use core::{mem, ptr, slice};
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
const SENTINEL: *mut libc::c_void = 1 as *mut libc::c_void;
fn must_succeed<T>(p: *mut T) -> *mut T { fn must_succeed<T>(p: *mut T) -> *mut T {
if p.is_null() { if p.is_null() {
panic!("allocation failure"); panic!("allocation failure");
@ -13,17 +11,28 @@ fn must_succeed<T>(p: *mut T) -> *mut T {
fn malloc<T>() -> *mut T { fn malloc<T>() -> *mut T {
let size = mem::size_of::<T>(); let size = mem::size_of::<T>();
let align = mem::align_of::<T>();
if size == 0 { if size == 0 {
return SENTINEL as *mut T; return align as *mut T;
} }
must_succeed( must_succeed(
unsafe {libc::memalign(mem::align_of::<T>() as libc::size_t, size as libc::size_t) } unsafe {
) as *mut T libc::memalign(align as libc::size_t, size as libc::size_t) as *mut T
}
)
} }
pub struct CBox<T: ?Sized>(*mut T); pub struct CBox<T>(*mut T);
impl<T> CBox<T> {
pub fn new(value: T) -> CBox<T> {
let p = malloc();
unsafe {
ptr::write(p, value);
CBox::from_raw(p)
}
}
impl<T: ?Sized> CBox<T> {
pub const unsafe fn from_raw(p: *mut T) -> CBox<T> { pub const unsafe fn from_raw(p: *mut T) -> CBox<T> {
CBox(p) CBox(p)
} }
@ -43,27 +52,18 @@ impl<T: ?Sized> CBox<T> {
} }
} }
impl<T> CBox<T> { impl<T> Drop for CBox<T> {
pub fn new(value: T) -> CBox<T> {
let p = malloc();
unsafe {
ptr::write(p, value);
CBox::from_raw(p)
}
}
}
impl<T: ?Sized> Drop for CBox<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { ptr::drop_in_place(self.0); } unsafe { ptr::drop_in_place(self.0); }
let p = self.0 as *mut libc::c_void; if mem::size_of::<T>() != 0 {
if p != SENTINEL { unsafe {
unsafe { libc::free(p); } libc::free(self.0 as *mut libc::c_void);
}
} }
} }
} }
impl<T: ?Sized> Deref for CBox<T> { impl<T> Deref for CBox<T> {
type Target = T; type Target = T;
fn deref(&self) -> &T { fn deref(&self) -> &T {
@ -71,7 +71,7 @@ impl<T: ?Sized> Deref for CBox<T> {
} }
} }
impl<T: ?Sized> DerefMut for CBox<T> { impl<T> DerefMut for CBox<T> {
fn deref_mut(&mut self) -> &mut T { fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.0 } unsafe { &mut *self.0 }
} }