about summary refs log tree commit diff
path: root/library/std
diff options
context:
space:
mode:
Diffstat (limited to 'library/std')
-rw-r--r--library/std/src/fs.rs12
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/unix/fs.rs2
-rw-r--r--library/std/src/os/unix/net/listener.rs14
-rw-r--r--library/std/src/sys/unix/thread.rs32
-rw-r--r--library/std/src/sys/unix/thread_local_dtor.rs2
-rw-r--r--library/std/src/thread/local.rs50
7 files changed, 62 insertions, 51 deletions
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 38050cf684f..c4a92927937 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -31,6 +31,10 @@ use crate::time::SystemTime;
 /// on closing are ignored by the implementation of `Drop`.  Use the method
 /// [`sync_all`] if these errors must be manually handled.
 ///
+/// `File` does not buffer reads and writes. For efficiency, consider wrapping the
+/// file in a [`BufReader`] or [`BufWriter`] when performing many small [`read`]
+/// or [`write`] calls, unless unbuffered reads and writes are required.
+///
 /// # Examples
 ///
 /// Creates a new file and write bytes to it (you can also use [`write()`]):
@@ -61,8 +65,7 @@ use crate::time::SystemTime;
 /// }
 /// ```
 ///
-/// It can be more efficient to read the contents of a file with a buffered
-/// [`Read`]er. This can be accomplished with [`BufReader<R>`]:
+/// Using a buffered [`Read`]er:
 ///
 /// ```no_run
 /// use std::fs::File;
@@ -93,8 +96,11 @@ use crate::time::SystemTime;
 /// perform synchronous I/O operations. Therefore the underlying file must not
 /// have been opened for asynchronous I/O (e.g. by using `FILE_FLAG_OVERLAPPED`).
 ///
-/// [`BufReader<R>`]: io::BufReader
+/// [`BufReader`]: io::BufReader
+/// [`BufWriter`]: io::BufReader
 /// [`sync_all`]: File::sync_all
+/// [`write`]: File::write
+/// [`read`]: File::read
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "File")]
 pub struct File {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 6365366297c..95ee6a9b29c 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -265,6 +265,7 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(not(bootstrap), feature(cfg_sanitizer_cfi))]
 #![feature(alloc_error_handler)]
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs
index 0eb4e88cfad..e995d5133f8 100644
--- a/library/std/src/os/unix/fs.rs
+++ b/library/std/src/os/unix/fs.rs
@@ -68,7 +68,7 @@ pub trait FileExt {
         io::default_read_vectored(|b| self.read_at(b, offset), bufs)
     }
 
-    /// Reads the exact number of byte required to fill `buf` from the given offset.
+    /// Reads the exact number of bytes required to fill `buf` from the given offset.
     ///
     /// The offset is relative to the start of the file and thus independent
     /// from the current cursor.
diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs
index 5be8aebc70f..1b70b669c77 100644
--- a/library/std/src/os/unix/net/listener.rs
+++ b/library/std/src/os/unix/net/listener.rs
@@ -73,8 +73,18 @@ impl UnixListener {
         unsafe {
             let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
             let (addr, len) = sockaddr_un(path.as_ref())?;
-            const backlog: libc::c_int =
-                if cfg!(any(target_os = "linux", target_os = "freebsd")) { -1 } else { 128 };
+            #[cfg(any(target_os = "windows", target_os = "redox"))]
+            const backlog: libc::c_int = 128;
+            #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))]
+            const backlog: libc::c_int = -1;
+            #[cfg(not(any(
+                target_os = "windows",
+                target_os = "redox",
+                target_os = "linux",
+                target_os = "freebsd",
+                target_os = "openbsd"
+            )))]
+            const backlog: libc::c_int = libc::SOMAXCONN;
 
             cvt(libc::bind(inner.as_inner().as_raw_fd(), &addr as *const _ as *const _, len as _))?;
             cvt(libc::listen(inner.as_inner().as_raw_fd(), backlog))?;
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 76b96bb37df..7e4a01a5ecd 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -354,7 +354,12 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                     Ok(unsafe { NonZeroUsize::new_unchecked(count) })
                 }
             }
-        } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] {
+        } else if #[cfg(any(
+                   target_os = "freebsd",
+                   target_os = "dragonfly",
+                   target_os = "openbsd",
+                   target_os = "netbsd",
+               ))] {
             use crate::ptr;
 
             #[cfg(target_os = "freebsd")]
@@ -427,31 +432,6 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                     return Err(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"));
                 }
             }
-            Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
-        } else if #[cfg(target_os = "openbsd")] {
-            use crate::ptr;
-
-            let mut cpus: libc::c_uint = 0;
-            let mut cpus_size = crate::mem::size_of_val(&cpus);
-            let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
-
-            let res = unsafe {
-                libc::sysctl(
-                    mib.as_mut_ptr(),
-                    2,
-                    &mut cpus as *mut _ as *mut _,
-                    &mut cpus_size as *mut _ as *mut _,
-                    ptr::null_mut(),
-                    0,
-                )
-            };
-
-            // Handle errors if any.
-            if res == -1 {
-                return Err(io::Error::last_os_error());
-            } else if cpus == 0 {
-                return Err(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"));
-            }
 
             Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
         } else if #[cfg(target_os = "nto")] {
diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs
index ac85531c372..58f7ab84101 100644
--- a/library/std/src/sys/unix/thread_local_dtor.rs
+++ b/library/std/src/sys/unix/thread_local_dtor.rs
@@ -11,7 +11,7 @@
 // Note, however, that we run on lots older linuxes, as well as cross
 // compiling from a newer linux to an older linux, so we also have a
 // fallback implementation to use as well.
-#[allow(unexpected_cfgs)]
+#[cfg_attr(bootstrap, allow(unexpected_cfgs))]
 #[cfg(any(
     target_os = "linux",
     target_os = "android",
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index def94acd457..9cf37b0e634 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -16,7 +16,8 @@ use crate::fmt;
 ///
 /// This key uses the fastest possible implementation available to it for the
 /// target platform. It is instantiated with the [`thread_local!`] macro and the
-/// primary method is the [`with`] method.
+/// primary method is the [`with`] method, though there are helpers to make
+/// working with [`Cell`] types easier.
 ///
 /// The [`with`] method yields a reference to the contained value which cannot
 /// outlive the current thread or escape the given closure.
@@ -25,14 +26,30 @@ use crate::fmt;
 ///
 /// # Initialization and Destruction
 ///
-/// Initialization is dynamically performed on the first call to [`with`]
-/// within a thread, and values that implement [`Drop`] get destructed when a
-/// thread exits. Some caveats apply, which are explained below.
+/// Initialization is dynamically performed on the first call to a setter (e.g.
+/// [`with`]) within a thread, and values that implement [`Drop`] get
+/// destructed when a thread exits. Some caveats apply, which are explained below.
 ///
 /// A `LocalKey`'s initializer cannot recursively depend on itself. Using a
 /// `LocalKey` in this way may cause panics, aborts or infinite recursion on
 /// the first call to `with`.
 ///
+/// # Single-thread Synchronization
+///
+/// Though there is no potential race with other threads, it is still possible to
+/// obtain multiple references to the thread-local data in different places on
+/// the call stack. For this reason, only shared (`&T`) references may be obtained.
+///
+/// To allow obtaining an exclusive mutable reference (`&mut T`), typically a
+/// [`Cell`] or [`RefCell`] is used (see the [`std::cell`] for more information
+/// on how exactly this works). To make this easier there are specialized
+/// implementations for [`LocalKey<Cell<T>>`] and [`LocalKey<RefCell<T>>`].
+///
+/// [`std::cell`]: `crate::cell`
+/// [`LocalKey<Cell<T>>`]: struct.LocalKey.html#impl-LocalKey<Cell<T>>
+/// [`LocalKey<RefCell<T>>`]: struct.LocalKey.html#impl-LocalKey<RefCell<T>>
+///
+///
 /// # Examples
 ///
 /// ```
@@ -41,26 +58,20 @@ use crate::fmt;
 ///
 /// thread_local!(static FOO: RefCell<u32> = RefCell::new(1));
 ///
-/// FOO.with(|f| {
-///     assert_eq!(*f.borrow(), 1);
-///     *f.borrow_mut() = 2;
-/// });
+/// FOO.with_borrow(|v| assert_eq!(*v, 1));
+/// FOO.with_borrow_mut(|v| *v = 2);
 ///
 /// // each thread starts out with the initial value of 1
 /// let t = thread::spawn(move|| {
-///     FOO.with(|f| {
-///         assert_eq!(*f.borrow(), 1);
-///         *f.borrow_mut() = 3;
-///     });
+///     FOO.with_borrow(|v| assert_eq!(*v, 1));
+///     FOO.with_borrow_mut(|v| *v = 3);
 /// });
 ///
 /// // wait for the thread to complete and bail out on panic
 /// t.join().unwrap();
 ///
 /// // we retain our original value of 2 despite the child thread
-/// FOO.with(|f| {
-///     assert_eq!(*f.borrow(), 2);
-/// });
+/// FOO.with_borrow(|v| assert_eq!(*v, 2));
 /// ```
 ///
 /// # Platform-specific behavior
@@ -137,10 +148,13 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
 ///     static BAR: RefCell<f32> = RefCell::new(1.0);
 /// }
 ///
-/// FOO.with(|foo| assert_eq!(*foo.borrow(), 1));
-/// BAR.with(|bar| assert_eq!(*bar.borrow(), 1.0));
+/// FOO.with_borrow(|v| assert_eq!(*v, 1));
+/// BAR.with_borrow(|v| assert_eq!(*v, 1.0));
 /// ```
 ///
+/// Note that only shared references (`&T`) to the inner data may be obtained, so a
+/// type such as [`Cell`] or [`RefCell`] is typically used to allow mutating access.
+///
 /// This macro supports a special `const {}` syntax that can be used
 /// when the initialization expression can be evaluated as a constant.
 /// This can enable a more efficient thread local implementation that
@@ -155,7 +169,7 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
 ///     pub static FOO: Cell<u32> = const { Cell::new(1) };
 /// }
 ///
-/// FOO.with(|foo| assert_eq!(foo.get(), 1));
+/// assert_eq!(FOO.get(), 1);
 /// ```
 ///
 /// See [`LocalKey` documentation][`std::thread::LocalKey`] for more