about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/sync/mpmc/array.rs2
-rw-r--r--library/std/src/sync/mpsc/mod.rs12
-rw-r--r--library/std/src/sys/itron/condvar.rs4
-rw-r--r--library/std/src/sys/itron/mutex.rs2
-rw-r--r--library/std/src/sys/itron/thread.rs48
-rw-r--r--library/std/src/sys/solid/io.rs4
-rw-r--r--library/std/src/sys/solid/os.rs3
-rw-r--r--library/std/src/sys/unix/weak.rs37
-rw-r--r--library/std/src/sys/windows/process.rs34
-rw-r--r--library/std/src/thread/scoped.rs2
10 files changed, 99 insertions, 49 deletions
diff --git a/library/std/src/sync/mpmc/array.rs b/library/std/src/sync/mpmc/array.rs
index 4db7b4990b9..f71edc6c525 100644
--- a/library/std/src/sync/mpmc/array.rs
+++ b/library/std/src/sync/mpmc/array.rs
@@ -225,7 +225,7 @@ impl<T> Channel<T> {
             let slot = unsafe { self.buffer.get_unchecked(index) };
             let stamp = slot.stamp.load(Ordering::Acquire);
 
-            // If the the stamp is ahead of the head by 1, we may attempt to pop.
+            // If the stamp is ahead of the head by 1, we may attempt to pop.
             if head + 1 == stamp {
                 let new = if index + 1 < self.cap {
                     // Same lap, incremented index.
diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs
index 27fba761ada..adb488d4378 100644
--- a/library/std/src/sync/mpsc/mod.rs
+++ b/library/std/src/sync/mpsc/mod.rs
@@ -629,9 +629,7 @@ impl<T> Clone for Sender<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Drop for Sender<T> {
-    fn drop(&mut self) {
-        let _ = self.inner;
-    }
+    fn drop(&mut self) {}
 }
 
 #[stable(feature = "mpsc_debug", since = "1.8.0")]
@@ -751,9 +749,7 @@ impl<T> Clone for SyncSender<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Drop for SyncSender<T> {
-    fn drop(&mut self) {
-        let _ = self.inner;
-    }
+    fn drop(&mut self) {}
 }
 
 #[stable(feature = "mpsc_debug", since = "1.8.0")]
@@ -1094,9 +1090,7 @@ impl<T> IntoIterator for Receiver<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Drop for Receiver<T> {
-    fn drop(&mut self) {
-        let _ = self.inner;
-    }
+    fn drop(&mut self) {}
 }
 
 #[stable(feature = "mpsc_debug", since = "1.8.0")]
diff --git a/library/std/src/sys/itron/condvar.rs b/library/std/src/sys/itron/condvar.rs
index f70aa434e48..7a47cc6696a 100644
--- a/library/std/src/sys/itron/condvar.rs
+++ b/library/std/src/sys/itron/condvar.rs
@@ -71,7 +71,7 @@ impl Condvar {
             }
         }
 
-        unsafe { mutex.lock() };
+        mutex.lock();
     }
 
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
@@ -109,7 +109,7 @@ impl Condvar {
         // we woke up because of `notify_*`.
         let success = self.waiters.with_locked(|waiters| unsafe { !waiters.remove(waiter) });
 
-        unsafe { mutex.lock() };
+        mutex.lock();
         success
     }
 }
diff --git a/library/std/src/sys/itron/mutex.rs b/library/std/src/sys/itron/mutex.rs
index f2eed8e771c..1f6cc419476 100644
--- a/library/std/src/sys/itron/mutex.rs
+++ b/library/std/src/sys/itron/mutex.rs
@@ -72,7 +72,7 @@ pub(super) struct MutexGuard<'a>(&'a Mutex);
 impl<'a> MutexGuard<'a> {
     #[inline]
     pub(super) fn lock(x: &'a Mutex) -> Self {
-        unsafe { x.lock() };
+        x.lock();
         Self(x)
     }
 }
diff --git a/library/std/src/sys/itron/thread.rs b/library/std/src/sys/itron/thread.rs
index d28f57f33be..c2b36680872 100644
--- a/library/std/src/sys/itron/thread.rs
+++ b/library/std/src/sys/itron/thread.rs
@@ -11,18 +11,25 @@ use crate::{
     ffi::CStr,
     hint, io,
     mem::ManuallyDrop,
+    ptr::NonNull,
     sync::atomic::{AtomicUsize, Ordering},
     sys::thread_local_dtor::run_dtors,
     time::Duration,
 };
 
 pub struct Thread {
-    inner: ManuallyDrop<Box<ThreadInner>>,
+    p_inner: NonNull<ThreadInner>,
 
     /// The ID of the underlying task.
     task: abi::ID,
 }
 
+// Safety: There's nothing in `Thread` that ties it to the original creator. It
+//         can be dropped by any threads.
+unsafe impl Send for Thread {}
+// Safety: `Thread` provides no methods that take `&self`.
+unsafe impl Sync for Thread {}
+
 /// State data shared between a parent thread and child thread. It's dropped on
 /// a transition to one of the final states.
 struct ThreadInner {
@@ -90,8 +97,9 @@ impl Thread {
         });
 
         unsafe extern "C" fn trampoline(exinf: isize) {
+            let p_inner: *mut ThreadInner = crate::ptr::from_exposed_addr_mut(exinf as usize);
             // Safety: `ThreadInner` is alive at this point
-            let inner = unsafe { &*(exinf as *const ThreadInner) };
+            let inner = unsafe { &*p_inner };
 
             // Safety: Since `trampoline` is called only once for each
             //         `ThreadInner` and only `trampoline` touches `start`,
@@ -119,13 +127,13 @@ impl Thread {
                     // No one will ever join, so we'll ask the collector task to
                     // delete the task.
 
-                    // In this case, `inner`'s ownership has been moved to us,
-                    // And we are responsible for dropping it. The acquire
+                    // In this case, `*p_inner`'s ownership has been moved to
+                    // us, and we are responsible for dropping it. The acquire
                     // ordering is not necessary because the parent thread made
                     // no memory access needing synchronization since the call
                     // to `acre_tsk`.
                     // Safety: See above.
-                    let _ = unsafe { Box::from_raw(inner as *const _ as *mut ThreadInner) };
+                    let _ = unsafe { Box::from_raw(p_inner) };
 
                     // Safety: There are no pinned references to the stack
                     unsafe { terminate_and_delete_current_task() };
@@ -162,13 +170,14 @@ impl Thread {
             }
         }
 
-        let inner_ptr = (&*inner) as *const ThreadInner;
+        // Safety: `Box::into_raw` returns a non-null pointer
+        let p_inner = unsafe { NonNull::new_unchecked(Box::into_raw(inner)) };
 
         let new_task = ItronError::err_if_negative(unsafe {
             abi::acre_tsk(&abi::T_CTSK {
                 // Activate this task immediately
                 tskatr: abi::TA_ACT,
-                exinf: inner_ptr as abi::EXINF,
+                exinf: p_inner.as_ptr().expose_addr() as abi::EXINF,
                 // The entry point
                 task: Some(trampoline),
                 // Inherit the calling task's base priority
@@ -180,7 +189,7 @@ impl Thread {
         })
         .map_err(|e| e.as_io_error())?;
 
-        Ok(Self { inner: ManuallyDrop::new(inner), task: new_task })
+        Ok(Self { p_inner, task: new_task })
     }
 
     pub fn yield_now() {
@@ -197,8 +206,9 @@ impl Thread {
         }
     }
 
-    pub fn join(mut self) {
-        let inner = &*self.inner;
+    pub fn join(self) {
+        // Safety: `ThreadInner` is alive at this point
+        let inner = unsafe { self.p_inner.as_ref() };
         // Get the current task ID. Panicking here would cause a resource leak,
         // so just abort on failure.
         let current_task = task::current_task_id_aborting();
@@ -243,8 +253,8 @@ impl Thread {
         unsafe { terminate_and_delete_task(self.task) };
 
         // In either case, we are responsible for dropping `inner`.
-        // Safety: The contents of `self.inner` will not be accessed hereafter
-        let _inner = unsafe { ManuallyDrop::take(&mut self.inner) };
+        // Safety: The contents of `*p_inner` will not be accessed hereafter
+        let _inner = unsafe { Box::from_raw(self.p_inner.as_ptr()) };
 
         // Skip the destructor (because it would attempt to detach the thread)
         crate::mem::forget(self);
@@ -253,13 +263,16 @@ impl Thread {
 
 impl Drop for Thread {
     fn drop(&mut self) {
+        // Safety: `ThreadInner` is alive at this point
+        let inner = unsafe { self.p_inner.as_ref() };
+
         // Detach the thread.
-        match self.inner.lifecycle.swap(LIFECYCLE_DETACHED_OR_JOINED, Ordering::Acquire) {
+        match inner.lifecycle.swap(LIFECYCLE_DETACHED_OR_JOINED, Ordering::Acquire) {
             LIFECYCLE_INIT => {
                 // [INIT → DETACHED]
                 // When the time comes, the child will figure out that no
                 // one will ever join it.
-                // The ownership of `self.inner` is moved to the child thread.
+                // The ownership of `*p_inner` is moved to the child thread.
                 // However, the release ordering is not necessary because we
                 // made no memory access needing synchronization since the call
                 // to `acre_tsk`.
@@ -278,10 +291,9 @@ impl Drop for Thread {
                 //         delete by entering the `FINISHED` state.
                 unsafe { terminate_and_delete_task(self.task) };
 
-                // Wwe are responsible for dropping `inner`.
-                // Safety: The contents of `self.inner` will not be accessed
-                //         hereafter
-                unsafe { ManuallyDrop::drop(&mut self.inner) };
+                // Wwe are responsible for dropping `*p_inner`.
+                // Safety: The contents of `*p_inner` will not be accessed hereafter
+                let _ = unsafe { Box::from_raw(self.p_inner.as_ptr()) };
             }
             _ => unsafe { hint::unreachable_unchecked() },
         }
diff --git a/library/std/src/sys/solid/io.rs b/library/std/src/sys/solid/io.rs
index 9eb17a10daa..a862bb78702 100644
--- a/library/std/src/sys/solid/io.rs
+++ b/library/std/src/sys/solid/io.rs
@@ -75,3 +75,7 @@ impl<'a> IoSliceMut<'a> {
         unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
 }
+
+pub fn is_terminal<T>(_: &T) -> bool {
+    false
+}
diff --git a/library/std/src/sys/solid/os.rs b/library/std/src/sys/solid/os.rs
index 4906c62689d..6135921f0b5 100644
--- a/library/std/src/sys/solid/os.rs
+++ b/library/std/src/sys/solid/os.rs
@@ -1,7 +1,6 @@
 use super::unsupported;
-use crate::convert::TryFrom;
 use crate::error::Error as StdError;
-use crate::ffi::{CStr, CString, OsStr, OsString};
+use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
 use crate::io;
 use crate::os::{
diff --git a/library/std/src/sys/unix/weak.rs b/library/std/src/sys/unix/weak.rs
index e4ff21b25bd..f5a4ce929b2 100644
--- a/library/std/src/sys/unix/weak.rs
+++ b/library/std/src/sys/unix/weak.rs
@@ -29,7 +29,21 @@ use crate::ptr;
 use crate::sync::atomic::{self, AtomicPtr, Ordering};
 
 // We can use true weak linkage on ELF targets.
-#[cfg(not(any(target_os = "macos", target_os = "ios")))]
+#[cfg(all(not(any(target_os = "macos", target_os = "ios")), not(bootstrap)))]
+pub(crate) macro weak {
+    (fn $name:ident($($t:ty),*) -> $ret:ty) => (
+        let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
+            extern "C" {
+                #[linkage = "extern_weak"]
+                static $name: Option<unsafe extern "C" fn($($t),*) -> $ret>;
+            }
+            #[allow(unused_unsafe)]
+            ExternWeak::new(unsafe { $name })
+        };
+    )
+}
+
+#[cfg(all(not(any(target_os = "macos", target_os = "ios")), bootstrap))]
 pub(crate) macro weak {
     (fn $name:ident($($t:ty),*) -> $ret:ty) => (
         let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
@@ -47,11 +61,31 @@ pub(crate) macro weak {
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 pub(crate) use self::dlsym as weak;
 
+#[cfg(not(bootstrap))]
+pub(crate) struct ExternWeak<F: Copy> {
+    weak_ptr: Option<F>,
+}
+
+#[cfg(not(bootstrap))]
+impl<F: Copy> ExternWeak<F> {
+    #[inline]
+    pub(crate) fn new(weak_ptr: Option<F>) -> Self {
+        ExternWeak { weak_ptr }
+    }
+
+    #[inline]
+    pub(crate) fn get(&self) -> Option<F> {
+        self.weak_ptr
+    }
+}
+
+#[cfg(bootstrap)]
 pub(crate) struct ExternWeak<F> {
     weak_ptr: *const libc::c_void,
     _marker: PhantomData<F>,
 }
 
+#[cfg(bootstrap)]
 impl<F> ExternWeak<F> {
     #[inline]
     pub(crate) fn new(weak_ptr: *const libc::c_void) -> Self {
@@ -59,6 +93,7 @@ impl<F> ExternWeak<F> {
     }
 }
 
+#[cfg(bootstrap)]
 impl<F> ExternWeak<F> {
     #[inline]
     pub(crate) fn get(&self) -> Option<F> {
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index 9cbb4ef19e9..31e9b34fb9e 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -252,10 +252,6 @@ impl Command {
     ) -> io::Result<(Process, StdioPipes)> {
         let maybe_env = self.env.capture_if_changed();
 
-        let mut si = zeroed_startupinfo();
-        si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD;
-        si.dwFlags = c::STARTF_USESTDHANDLES;
-
         let child_paths = if let Some(env) = maybe_env.as_ref() {
             env.get(&EnvKey::new("PATH")).map(|s| s.as_os_str())
         } else {
@@ -314,9 +310,21 @@ impl Command {
         let stdin = stdin.to_handle(c::STD_INPUT_HANDLE, &mut pipes.stdin)?;
         let stdout = stdout.to_handle(c::STD_OUTPUT_HANDLE, &mut pipes.stdout)?;
         let stderr = stderr.to_handle(c::STD_ERROR_HANDLE, &mut pipes.stderr)?;
-        si.hStdInput = stdin.as_raw_handle();
-        si.hStdOutput = stdout.as_raw_handle();
-        si.hStdError = stderr.as_raw_handle();
+
+        let mut si = zeroed_startupinfo();
+        si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD;
+
+        // If at least one of stdin, stdout or stderr are set (i.e. are non null)
+        // then set the `hStd` fields in `STARTUPINFO`.
+        // Otherwise skip this and allow the OS to apply its default behaviour.
+        // This provides more consistent behaviour between Win7 and Win8+.
+        let is_set = |stdio: &Handle| !stdio.as_raw_handle().is_null();
+        if is_set(&stderr) || is_set(&stdout) || is_set(&stdin) {
+            si.dwFlags |= c::STARTF_USESTDHANDLES;
+            si.hStdInput = stdin.as_raw_handle();
+            si.hStdOutput = stdout.as_raw_handle();
+            si.hStdError = stderr.as_raw_handle();
+        }
 
         unsafe {
             cvt(c::CreateProcessW(
@@ -513,9 +521,6 @@ fn program_exists(path: &Path) -> Option<Vec<u16>> {
 impl Stdio {
     fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>) -> io::Result<Handle> {
         match *self {
-            // If no stdio handle is available, then inherit means that it
-            // should still be unavailable so propagate the
-            // INVALID_HANDLE_VALUE.
             Stdio::Inherit => match stdio::get_handle(stdio_id) {
                 Ok(io) => unsafe {
                     let io = Handle::from_raw_handle(io);
@@ -523,7 +528,8 @@ impl Stdio {
                     io.into_raw_handle();
                     ret
                 },
-                Err(..) => unsafe { Ok(Handle::from_raw_handle(c::INVALID_HANDLE_VALUE)) },
+                // If no stdio handle is available, then propagate the null value.
+                Err(..) => unsafe { Ok(Handle::from_raw_handle(ptr::null_mut())) },
             },
 
             Stdio::MakePipe => {
@@ -730,9 +736,9 @@ fn zeroed_startupinfo() -> c::STARTUPINFO {
         wShowWindow: 0,
         cbReserved2: 0,
         lpReserved2: ptr::null_mut(),
-        hStdInput: c::INVALID_HANDLE_VALUE,
-        hStdOutput: c::INVALID_HANDLE_VALUE,
-        hStdError: c::INVALID_HANDLE_VALUE,
+        hStdInput: ptr::null_mut(),
+        hStdOutput: ptr::null_mut(),
+        hStdError: ptr::null_mut(),
     }
 }
 
diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs
index e6dbf35bd02..ada69aa8269 100644
--- a/library/std/src/thread/scoped.rs
+++ b/library/std/src/thread/scoped.rs
@@ -46,7 +46,7 @@ impl ScopeData {
         // We check for 'overflow' with usize::MAX / 2, to make sure there's no
         // chance it overflows to 0, which would result in unsoundness.
         if self.num_running_threads.fetch_add(1, Ordering::Relaxed) > usize::MAX / 2 {
-            // This can only reasonably happen by mem::forget()'ing many many ScopedJoinHandles.
+            // This can only reasonably happen by mem::forget()'ing a lot of ScopedJoinHandles.
             self.decrement_num_running_threads(false);
             panic!("too many running threads in thread scope");
         }