diff options
Diffstat (limited to 'library/std')
| -rw-r--r-- | library/std/src/fs.rs | 12 | ||||
| -rw-r--r-- | library/std/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/std/src/os/unix/fs.rs | 2 | ||||
| -rw-r--r-- | library/std/src/os/unix/net/listener.rs | 14 | ||||
| -rw-r--r-- | library/std/src/sys/unix/thread.rs | 32 | ||||
| -rw-r--r-- | library/std/src/sys/unix/thread_local_dtor.rs | 2 | ||||
| -rw-r--r-- | library/std/src/thread/local.rs | 50 |
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 |
