Skip to content

Commit

Permalink
Use Box::into_raw instead of ManuallyDrop in Thread::new.
Browse files Browse the repository at this point in the history
  • Loading branch information
Vytautas Astrauskas committed Apr 1, 2020
1 parent 753bc7d commit 5382347
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 36 deletions.
13 changes: 4 additions & 9 deletions src/libstd/sys/cloudabi/thread.rs
Expand Up @@ -22,26 +22,21 @@ unsafe impl Sync for Thread {}
impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
let mut p = mem::ManuallyDrop::new(box p);
let p = Box::into_raw(box p);
let mut native: libc::pthread_t = mem::zeroed();
let mut attr: libc::pthread_attr_t = mem::zeroed();
assert_eq!(libc::pthread_attr_init(&mut attr), 0);

let stack_size = cmp::max(stack, min_stack_size(&attr));
assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);

let ret = libc::pthread_create(
&mut native,
&attr,
thread_start,
&mut *p as &mut Box<dyn FnOnce()> as *mut _ as *mut _,
);
let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);

return if ret != 0 {
// The thread failed to start and as a result p was not consumed. Therefore, it is
// safe to manually drop it.
mem::ManuallyDrop::drop(&mut p);
// safe to reconstruct the box so that it gets deallocated.
let _ = Box::from_raw(p);
Err(io::Error::from_raw_os_error(ret))
} else {
Ok(Thread { id: native })
Expand Down
8 changes: 4 additions & 4 deletions src/libstd/sys/hermit/thread.rs
Expand Up @@ -48,20 +48,20 @@ impl Thread {
p: Box<dyn FnOnce()>,
core_id: isize,
) -> io::Result<Thread> {
let mut p = mem::ManuallyDrop::new(box p);
let p = Box::into_raw(box p);
let mut tid: Tid = u32::MAX;
let ret = abi::spawn(
&mut tid as *mut Tid,
thread_start,
&mut *p as &mut Box<dyn FnOnce()> as *mut _ as *mut u8 as usize,
p as *mut u8 as usize,
Priority::into(NORMAL_PRIO),
core_id,
);

return if ret != 0 {
// The thread failed to start and as a result p was not consumed. Therefore, it is
// safe to manually drop it.
mem::ManuallyDrop::drop(&mut p);
// safe to reconstruct the box so that it gets deallocated.
let _ = Box::from_raw(p);
Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!"))
} else {
Ok(Thread { tid: tid })
Expand Down
13 changes: 4 additions & 9 deletions src/libstd/sys/unix/thread.rs
Expand Up @@ -41,7 +41,7 @@ unsafe fn pthread_attr_setstacksize(
impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
let mut p = mem::ManuallyDrop::new(box p);
let p = Box::into_raw(box p);
let mut native: libc::pthread_t = mem::zeroed();
let mut attr: libc::pthread_attr_t = mem::zeroed();
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
Expand All @@ -63,18 +63,13 @@ impl Thread {
}
};

let ret = libc::pthread_create(
&mut native,
&attr,
thread_start,
&mut *p as &mut Box<dyn FnOnce()> as *mut _ as *mut _,
);
let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);

return if ret != 0 {
// The thread failed to start and as a result p was not consumed. Therefore, it is
// safe to manually drop it.
mem::ManuallyDrop::drop(&mut p);
// safe to reconstruct the box so that it gets deallocated.
let _ = Box::from_raw(p);
Err(io::Error::from_raw_os_error(ret))
} else {
Ok(Thread { id: native })
Expand Down
13 changes: 4 additions & 9 deletions src/libstd/sys/vxworks/thread.rs
Expand Up @@ -29,7 +29,7 @@ unsafe fn pthread_attr_setstacksize(
impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
let mut p = mem::ManuallyDrop::new(box p);
let p = Box::into_raw(box p);
let mut native: libc::pthread_t = mem::zeroed();
let mut attr: libc::pthread_attr_t = mem::zeroed();
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
Expand All @@ -51,18 +51,13 @@ impl Thread {
}
};

let ret = libc::pthread_create(
&mut native,
&attr,
thread_start,
&mut *p as &mut Box<dyn FnOnce()> as *mut _ as *mut _,
);
let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);

return if ret != 0 {
// The thread failed to start and as a result p was not consumed. Therefore, it is
// safe to manually drop it.
mem::ManuallyDrop::drop(&mut p);
// safe to reconstruct the box so that it gets deallocated.
let _ = Box::from_raw(p);
Err(io::Error::from_raw_os_error(ret))
} else {
Ok(Thread { id: native })
Expand Down
9 changes: 4 additions & 5 deletions src/libstd/sys/windows/thread.rs
@@ -1,6 +1,5 @@
use crate::ffi::CStr;
use crate::io;
use crate::mem;
use crate::ptr;
use crate::sys::c;
use crate::sys::handle::Handle;
Expand All @@ -20,7 +19,7 @@ pub struct Thread {
impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
let mut p = mem::ManuallyDrop::new(box p);
let p = Box::into_raw(box p);

// FIXME On UNIX, we guard against stack sizes that are too small but
// that's because pthreads enforces that stacks are at least
Expand All @@ -34,15 +33,15 @@ impl Thread {
ptr::null_mut(),
stack_size,
thread_start,
&mut *p as &mut Box<dyn FnOnce()> as *mut _ as *mut _,
p as *mut _,
c::STACK_SIZE_PARAM_IS_A_RESERVATION,
ptr::null_mut(),
);

return if ret as usize == 0 {
// The thread failed to start and as a result p was not consumed. Therefore, it is
// safe to manually drop it.
mem::ManuallyDrop::drop(&mut p);
// safe to reconstruct the box so that it gets deallocated.
let _ = Box::from_raw(p);
Err(io::Error::last_os_error())
} else {
Ok(Thread { handle: Handle::new(ret) })
Expand Down

0 comments on commit 5382347

Please sign in to comment.