Skip to content

Commit c559216

Browse files
author
Jethro Beekman
committed
Change sys::Thread::new to take the thread entry as Box<dyn FnBox() + 'static>̣
1 parent 6c03640 commit c559216

File tree

6 files changed

+29
-8
lines changed

6 files changed

+29
-8
lines changed

src/libstd/sys/cloudabi/thread.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ unsafe impl Send for Thread {}
3232
unsafe impl Sync for Thread {}
3333

3434
impl Thread {
35-
pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> {
35+
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
36+
pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
3637
let p = box p;
3738
let mut native: libc::pthread_t = mem::zeroed();
3839
let mut attr: libc::pthread_attr_t = mem::zeroed();

src/libstd/sys/redox/thread.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ unsafe impl Send for Thread {}
2828
unsafe impl Sync for Thread {}
2929

3030
impl Thread {
31-
pub unsafe fn new<'a>(_stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> {
31+
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
32+
pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
3233
let p = box p;
3334

3435
let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?;

src/libstd/sys/unix/thread.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
4949
}
5050

5151
impl Thread {
52-
pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
52+
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
53+
pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
5354
-> io::Result<Thread> {
5455
let p = box p;
5556
let mut native: libc::pthread_t = mem::zeroed();

src/libstd/sys/wasm/thread.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ pub struct Thread(Void);
1919
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
2020

2121
impl Thread {
22-
pub unsafe fn new<'a>(_stack: usize, _p: Box<dyn FnBox() + 'a>)
22+
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
23+
pub unsafe fn new(_stack: usize, _p: Box<dyn FnBox()>)
2324
-> io::Result<Thread>
2425
{
2526
unsupported()

src/libstd/sys/windows/thread.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ pub struct Thread {
2828
}
2929

3030
impl Thread {
31-
pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
31+
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
32+
pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
3233
-> io::Result<Thread> {
3334
let p = box p;
3435

src/libstd/thread/mod.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,12 @@
167167
#![stable(feature = "rust1", since = "1.0.0")]
168168

169169
use any::Any;
170+
use boxed::FnBox;
170171
use cell::UnsafeCell;
171172
use ffi::{CStr, CString};
172173
use fmt;
173174
use io;
175+
use mem;
174176
use panic;
175177
use panicking;
176178
use str;
@@ -452,8 +454,8 @@ impl Builder {
452454
/// [`io::Result`]: ../../std/io/type.Result.html
453455
/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
454456
#[unstable(feature = "thread_spawn_unchecked", issue = "55132")]
455-
pub unsafe fn spawn_unchecked<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
456-
F: FnOnce() -> T, F: Send, T: Send
457+
pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
458+
F: FnOnce() -> T, F: Send + 'a, T: Send + 'a
457459
{
458460
let Builder { name, stack_size } = self;
459461

@@ -482,7 +484,21 @@ impl Builder {
482484
};
483485

484486
Ok(JoinHandle(JoinInner {
485-
native: Some(imp::Thread::new(stack_size, Box::new(main))?),
487+
// `imp::Thread::new` takes a closure with a `'static` lifetime, since it's passed
488+
// through FFI or otherwise used with low-level threading primitives that have no
489+
// notion of or way to enforce lifetimes.
490+
//
491+
// As mentioned in the `Safety` section of this function's documentation, the caller of
492+
// this function needs to guarantee that the passed-in lifetime is sufficiently long
493+
// for the lifetime of the thread.
494+
//
495+
// Similarly, the `sys` implementation must guarantee that no references to the closure
496+
// exist after the thread has terminated, which is signaled by `Thread::join`
497+
// returning.
498+
native: Some(imp::Thread::new(
499+
stack_size,
500+
mem::transmute::<Box<dyn FnBox() + 'a>, Box<dyn FnBox() + 'static>>(Box::new(main))
501+
)?),
486502
thread: my_thread,
487503
packet: Packet(my_packet),
488504
}))

0 commit comments

Comments
 (0)