diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 45f16a750963f..5ce4e0794661d 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -5,7 +5,6 @@ use crate::io; use crate::mem; use crate::num::NonZero; use crate::ptr; -use crate::sync::Arc; use crate::sys::{os, stack_overflow}; use crate::time::Duration; @@ -113,43 +112,6 @@ impl Thread { } } - pub unsafe fn new_reactor(p: F) -> io::Result - where F: Fn() + Send + Sync + 'static { - let p = Arc::new(p); - let p = Arc::into_raw(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 ret = libc::pthread_create(&mut native, &attr, reactor_start, p as *mut _); - // Note: if the thread creation fails and this assert fails, then p will - // be leaked. However, an alternative design could cause double-free - // which is clearly worse. - 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 reconstruct the box so that it gets deallocated. - drop(Arc::from_raw(p)); - Err(io::Error::from_raw_os_error(ret)) - } else { - Ok(Thread { id: native }) - }; - - extern "C" fn reactor_start(main: *mut libc::c_void) -> *mut libc::c_void { - unsafe { - // Next, set up our stack overflow handler which may get triggered if we run - // out of stack. - let _handler = stack_overflow::Handler::new(); - // Finally, let's run some code. - let f = Arc::from_raw(main as *mut Arc); - f(); - crate::mem::forget(f); - } - ptr::null_mut() - } - } - pub fn yield_now() { let ret = unsafe { libc::sched_yield() }; debug_assert_eq!(ret, 0); diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/pal/unsupported/thread.rs index afad3bb6e1b0c..2db957d1353bd 100644 --- a/library/std/src/sys/pal/unsupported/thread.rs +++ b/library/std/src/sys/pal/unsupported/thread.rs @@ -15,11 +15,6 @@ impl Thread { unsupported() } - pub unsafe fn new_reactor(p: F) -> io::Result - where F: Fn() + Send + Sync + 'static { - unsupported() - } - pub fn yield_now() { // do nothing } diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index f45fa5a6ba92b..780b8e5010a81 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -125,13 +125,6 @@ impl Thread { } } - pub unsafe fn new_reactor(_p: F) -> io::Result - where - F: Fn() + Send + Sync + 'static, - { - unsupported() - } - pub fn yield_now() { let ret = unsafe { wasi::sched_yield() }; debug_assert_eq!(ret, Ok(())); diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs index 8ecd950714714..484bd08495eef 100644 --- a/library/std/src/sys/pal/wasm/atomics/thread.rs +++ b/library/std/src/sys/pal/wasm/atomics/thread.rs @@ -14,11 +14,6 @@ impl Thread { unsupported() } - pub unsafe fn new_reactor(p: F) -> io::Result - where F: Fn() + Send + Sync + 'static { - unsupported() - } - pub fn yield_now() {} pub fn set_name(_name: &CStr) {} diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs index e905b388e1ff6..9e15b15a3513a 100644 --- a/library/std/src/sys/pal/windows/net.rs +++ b/library/std/src/sys/pal/windows/net.rs @@ -209,10 +209,6 @@ impl Socket { } } - pub fn accept_timeout(&self, _storage: *mut c::SOCKADDR, _len: *mut c_int, _timeout: crate::time::Duration) -> io::Result { - super::unsupported::unsupported() - } - pub fn duplicate(&self) -> io::Result { Ok(Self(self.0.try_clone()?)) } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 58253e13c136e..417acea22d663 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -387,46 +387,6 @@ impl Builder { unsafe { self.spawn_unchecked(f) } } - /// Spawns a new reactor by taking ownership of the `Builder`, and returns an - /// [`io::Result`]. - /// - /// The spawned reactor may outlive the caller (unless the caller thread - /// is the main thread; the whole process is terminated when the main - /// thread finishes). - /// - /// # Errors - /// - /// Unlike the [`spawn`] free function, this method yields an - /// [`io::Result`] to capture any failure to create the thread at - /// the OS level. - /// - /// [`io::Result`]: crate::io::Result - /// - /// # Panics - /// - /// Panics if a reactor name was set and it contained null bytes. - /// - /// # Examples - /// - /// ``` - /// use std::thread; - /// - /// let builder = thread::Builder::new(); - /// - /// builder.reactor(|| { - /// // reactor code - /// }).unwrap(); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn reactor(self, f: F) -> io::Result<()> - where - F: Fn(), - F: Send + Sync + 'static, - { - unsafe { imp::Thread::new_reactor(f)? }; - Ok(()) - } - /// Spawns a new thread without any lifetime restrictions by taking ownership /// of the `Builder`, and returns an [`io::Result`] to its [`JoinHandle`]. /// @@ -762,89 +722,6 @@ pub(crate) fn try_current() -> Option { CURRENT.try_with(|current| current.get_or_init(|| Thread::new_unnamed()).clone()).ok() } -//////////////////////////////////////////////////////////////////////////////// -// Free functions -//////////////////////////////////////////////////////////////////////////////// - -/// Spawns a new reactor -/// -/// This call will create a reactor using default parameters of [`Builder`], if you -/// want to specify the stack size or the name of the reactor, use this API -/// instead. -/// -/// As you can see in the signature of `reactor` there are two constraints on -/// the closure given to `reactor`, let's explain them: -/// -/// - The `'static` constraint means that the closure must have a lifetime of the -/// whole program execution. The reason for this is that reactors will be -/// continuously invoked by outside of the program until it exists -/// -/// Indeed if the reactor, can outlive their caller, we need to make sure that -/// they will be valid afterwards, thus is until the end of the program, hence -/// he `'static` lifetime. -/// - The [`Send`] constraint is because the closure will need to be passed -/// *by value* from the thread where it is spawned to the new thread. Its -/// return value will need to be passed from the new thread to the thread -/// where it is `join`ed. -/// As a reminder, the [`Send`] marker trait expresses that it is safe to be -/// passed from thread to thread. [`Sync`] expresses that it is safe to have a -/// reference be passed from thread to thread. -/// -/// # Panics -/// -/// Panics if the OS fails to create a thread; use [`Builder::reactor`] -/// to recover from such errors. -/// -/// # Examples -/// -/// Creating a thread. -/// -/// ``` -/// use std::thread; -/// -/// thread::reactor(|| { -/// // reactor code -/// }); -/// ``` -/// -/// As mentioned in the module documentation, reactors are usually made to -/// communicate using [`channels`], here is how it usually looks. -/// -/// This example also shows how to use `move`, in order to give ownership -/// of values to a reactor. -/// -/// ``` -/// use std::thread; -/// use std::sync::{Arc, Mutex}; -/// use std::sync::mpsc::channel; -/// -/// let (tx, rx) = channel(); -/// let tx = Arc::new(Mutex::new(tx)); -/// -/// let sender = thread::reactor(move || { -/// tx.lock().unwrap().send("Hello, thread".to_owned()) -/// .expect("Unable to send on channel"); -/// }); -/// -/// let receiver = thread::thread(move || { -/// let value = rx.recv().expect("Unable to receive from channel"); -/// println!("{value}"); -/// }); -/// -/// receiver.join().expect("The receiver thread has panicked"); -/// ``` -/// -/// [`channels`]: crate::sync::mpsc -/// [`Err`]: crate::result::Result::Err -#[stable(feature = "rust1", since = "1.0.0")] -pub fn reactor(f: F) -where - F: Fn(), - F: Send + Sync + 'static, -{ - Builder::new().reactor(f).expect("failed to spawn reactor") -} - /// Gets a handle to the thread that invokes it. /// /// # Examples