diff options
| author | bors <bors@rust-lang.org> | 2021-04-25 04:45:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-04-25 04:45:39 +0000 |
| commit | 5da10c01214a3d3ebec65b8ba6effada92a0673f (patch) | |
| tree | 94bbe380b059b6f77025a1e7c8d290f62390998e /library/std/src/sys | |
| parent | f7c468fe9a1448b1f6ceee6a4c831fe6122a54f0 (diff) | |
| parent | 7171fec13f3a3091f702a8e55f495ad1563dc4cd (diff) | |
| download | rust-5da10c01214a3d3ebec65b8ba6effada92a0673f.tar.gz rust-5da10c01214a3d3ebec65b8ba6effada92a0673f.zip | |
Auto merge of #84115 - CDirkx:rt, r=m-ou-se
Rework `init` and `cleanup` This PR reworks the code in `std` that runs before and after `main` and centralizes this code respectively in the functions `init` and `cleanup` in both `sys_common` and `sys`. This makes is easy to see what code is executed during initialization and cleanup on each platform just by looking at e.g. `sys::windows::init`. Full list of changes: - new module `rt` in `sys_common` to contain `init` and `cleanup` and the runtime macros. - `at_exit` and the mechanism to register exit handlers has been completely removed. In practice this was only used for closing sockets on windows and flushing stdout, which have been moved to `cleanup`. - <s>On windows `alloc` and `net` initialization is now done in `init`, this saves a runtime check in every allocation and network use.</s>
Diffstat (limited to 'library/std/src/sys')
| -rw-r--r-- | library/std/src/sys/hermit/mod.rs | 13 | ||||
| -rw-r--r-- | library/std/src/sys/hermit/stack_overflow.rs | 5 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/args.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/mod.rs | 14 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/stack_overflow.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/unix/mod.rs | 62 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/args.rs | 3 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/common.rs | 9 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/mod.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/stack_overflow.rs | 3 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/args.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasm/args.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/wasm/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/windows/args.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/windows/mod.rs | 13 | ||||
| -rw-r--r-- | library/std/src/sys/windows/net.rs | 19 | ||||
| -rw-r--r-- | library/std/src/sys/windows/stack_overflow.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/windows/stack_overflow_uwp.rs | 2 |
19 files changed, 81 insertions, 89 deletions
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index 56497162c03..a70d1db7ca6 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -37,7 +37,6 @@ pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; pub mod rwlock; -pub mod stack_overflow; pub mod stdio; pub mod thread; pub mod thread_local_dtor; @@ -96,9 +95,17 @@ pub extern "C" fn __rust_abort() { abort_internal(); } -#[cfg(not(test))] -pub fn init() { +// SAFETY: must be called only once during runtime initialization. +// NOTE: this is not guaranteed to run, for example when Rust code is called externally. +pub unsafe fn init(argc: isize, argv: *const *const u8) { let _ = net::init(); + args::init(argc, argv); +} + +// SAFETY: must be called only once during runtime cleanup. +// NOTE: this is not guaranteed to run, for example when the program aborts. +pub unsafe fn cleanup() { + args::cleanup(); } #[cfg(not(test))] diff --git a/library/std/src/sys/hermit/stack_overflow.rs b/library/std/src/sys/hermit/stack_overflow.rs deleted file mode 100644 index 121fe42011d..00000000000 --- a/library/std/src/sys/hermit/stack_overflow.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[inline] -pub unsafe fn init() {} - -#[inline] -pub unsafe fn cleanup() {} diff --git a/library/std/src/sys/sgx/args.rs b/library/std/src/sys/sgx/args.rs index 463188ad7c0..ef4176c4ac0 100644 --- a/library/std/src/sys/sgx/args.rs +++ b/library/std/src/sys/sgx/args.rs @@ -23,8 +23,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { } } -pub unsafe fn cleanup() {} - pub fn args() -> Args { let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() }; if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) } diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs index d6a56830733..059d6cb5ba1 100644 --- a/library/std/src/sys/sgx/mod.rs +++ b/library/std/src/sys/sgx/mod.rs @@ -32,7 +32,6 @@ pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; pub mod rwlock; -pub mod stack_overflow; pub mod stdio; pub mod thread; pub mod thread_local_key; @@ -40,8 +39,17 @@ pub mod time; pub use crate::sys_common::os_str_bytes as os_str; -#[cfg(not(test))] -pub fn init() {} +// SAFETY: must be called only once during runtime initialization. +// NOTE: this is not guaranteed to run, for example when Rust code is called externally. +pub unsafe fn init(argc: isize, argv: *const *const u8) { + unsafe { + args::init(argc, argv); + } +} + +// SAFETY: must be called only once during runtime cleanup. +// NOTE: this is not guaranteed to run, for example when the program aborts. +pub unsafe fn cleanup() {} /// This function is used to implement functionality that simply doesn't exist. /// Programs relying on this functionality will need to deal with the error. diff --git a/library/std/src/sys/sgx/stack_overflow.rs b/library/std/src/sys/sgx/stack_overflow.rs deleted file mode 100644 index b96652a8330..00000000000 --- a/library/std/src/sys/sgx/stack_overflow.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[cfg_attr(test, allow(dead_code))] -pub unsafe fn init() {} - -pub unsafe fn cleanup() {} diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 1316835a89d..a0ee69c2f72 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -44,14 +44,13 @@ pub mod time; pub use crate::sys_common::os_str_bytes as os_str; -#[cfg(not(test))] -pub fn init() { +// SAFETY: must be called only once during runtime initialization. +// NOTE: this is not guaranteed to run, for example when Rust code is called externally. +pub unsafe fn init(argc: isize, argv: *const *const u8) { // The standard streams might be closed on application startup. To prevent // std::io::{stdin, stdout,stderr} objects from using other unrelated file // resources opened later, we reopen standards streams when they are closed. - unsafe { - sanitize_standard_fds(); - } + sanitize_standard_fds(); // By default, some platforms will send a *signal* when an EPIPE error // would otherwise be delivered. This runtime doesn't install a SIGPIPE @@ -60,26 +59,24 @@ pub fn init() { // // Hence, we set SIGPIPE to ignore when the program starts up in order // to prevent this problem. - unsafe { - reset_sigpipe(); - } + reset_sigpipe(); + + stack_overflow::init(); + args::init(argc, argv); - cfg_if::cfg_if! { - if #[cfg(miri)] { - // The standard fds are always available in Miri. - unsafe fn sanitize_standard_fds() {} - } else if #[cfg(not(any( - target_os = "emscripten", - target_os = "fuchsia", - target_os = "vxworks", - // The poll on Darwin doesn't set POLLNVAL for closed fds. - target_os = "macos", - target_os = "ios", - target_os = "redox", - )))] { - // In the case when all file descriptors are open, the poll has been - // observed to perform better than fcntl (on GNU/Linux). - unsafe fn sanitize_standard_fds() { + unsafe fn sanitize_standard_fds() { + #[cfg(not(miri))] + // The standard fds are always available in Miri. + cfg_if::cfg_if! { + if #[cfg(not(any( + target_os = "emscripten", + target_os = "fuchsia", + target_os = "vxworks", + // The poll on Darwin doesn't set POLLNVAL for closed fds. + target_os = "macos", + target_os = "ios", + target_os = "redox", + )))] { use crate::sys::os::errno; let pfds: &mut [_] = &mut [ libc::pollfd { fd: 0, events: 0, revents: 0 }, @@ -104,9 +101,7 @@ pub fn init() { libc::abort(); } } - } - } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "redox"))] { - unsafe fn sanitize_standard_fds() { + } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "redox"))] { use crate::sys::os::errno; for fd in 0..3 { if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { @@ -116,17 +111,20 @@ pub fn init() { } } } - } else { - unsafe fn sanitize_standard_fds() {} } } - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia")))] unsafe fn reset_sigpipe() { + #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia")))] assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR); } - #[cfg(any(target_os = "emscripten", target_os = "fuchsia"))] - unsafe fn reset_sigpipe() {} +} + +// SAFETY: must be called only once during runtime cleanup. +// NOTE: this is not guaranteed to run, for example when the program aborts. +pub unsafe fn cleanup() { + args::cleanup(); + stack_overflow::cleanup(); } #[cfg(target_os = "android")] diff --git a/library/std/src/sys/unsupported/args.rs b/library/std/src/sys/unsupported/args.rs index 360bb65af69..c924a7d8a26 100644 --- a/library/std/src/sys/unsupported/args.rs +++ b/library/std/src/sys/unsupported/args.rs @@ -1,8 +1,5 @@ use crate::ffi::OsString; -pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} -pub unsafe fn cleanup() {} - pub struct Args {} pub fn args() -> Args { diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs index 0ef84c84ee8..6e72a7c632e 100644 --- a/library/std/src/sys/unsupported/common.rs +++ b/library/std/src/sys/unsupported/common.rs @@ -10,8 +10,13 @@ pub use crate::sys_common::os_str_bytes as os_str; // spec definition? use crate::os::raw::c_char; -#[cfg(not(test))] -pub fn init() {} +// SAFETY: must be called only once during runtime initialization. +// NOTE: this is not guaranteed to run, for example when Rust code is called externally. +pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} + +// SAFETY: must be called only once during runtime cleanup. +// NOTE: this is not guaranteed to run, for example when the program aborts. +pub unsafe fn cleanup() {} pub fn unsupported<T>() -> std_io::Result<T> { Err(unsupported_err()) diff --git a/library/std/src/sys/unsupported/mod.rs b/library/std/src/sys/unsupported/mod.rs index d9efdec33d9..32ca68ef15b 100644 --- a/library/std/src/sys/unsupported/mod.rs +++ b/library/std/src/sys/unsupported/mod.rs @@ -15,7 +15,6 @@ pub mod path; pub mod pipe; pub mod process; pub mod rwlock; -pub mod stack_overflow; pub mod stdio; pub mod thread; #[cfg(target_thread_local)] diff --git a/library/std/src/sys/unsupported/stack_overflow.rs b/library/std/src/sys/unsupported/stack_overflow.rs deleted file mode 100644 index 32555394cd5..00000000000 --- a/library/std/src/sys/unsupported/stack_overflow.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub unsafe fn init() {} - -pub unsafe fn cleanup() {} diff --git a/library/std/src/sys/wasi/args.rs b/library/std/src/sys/wasi/args.rs index 3c3e66985b3..c42c310e3a2 100644 --- a/library/std/src/sys/wasi/args.rs +++ b/library/std/src/sys/wasi/args.rs @@ -5,10 +5,6 @@ use crate::fmt; use crate::os::wasi::ffi::OsStrExt; use crate::vec; -pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} - -pub unsafe fn cleanup() {} - pub struct Args { iter: vec::IntoIter<OsString>, } diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs index b7b640b174f..2584d35b6ef 100644 --- a/library/std/src/sys/wasi/mod.rs +++ b/library/std/src/sys/wasi/mod.rs @@ -42,8 +42,6 @@ pub mod pipe; pub mod process; #[path = "../unsupported/rwlock.rs"] pub mod rwlock; -#[path = "../unsupported/stack_overflow.rs"] -pub mod stack_overflow; pub mod stdio; pub mod thread; #[path = "../unsupported/thread_local_dtor.rs"] diff --git a/library/std/src/sys/wasm/args.rs b/library/std/src/sys/wasm/args.rs index 99161ee056a..fde1ab79e1f 100644 --- a/library/std/src/sys/wasm/args.rs +++ b/library/std/src/sys/wasm/args.rs @@ -2,12 +2,6 @@ use crate::ffi::OsString; use crate::fmt; use crate::vec; -pub unsafe fn init(_argc: isize, _argv: *const *const u8) { - // On wasm these should always be null, so there's nothing for us to do here -} - -pub unsafe fn cleanup() {} - pub fn args() -> Args { Args { iter: Vec::new().into_iter() } } diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index 82683c0f624..8705910c73a 100644 --- a/library/std/src/sys/wasm/mod.rs +++ b/library/std/src/sys/wasm/mod.rs @@ -35,8 +35,6 @@ pub mod path; pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; -#[path = "../unsupported/stack_overflow.rs"] -pub mod stack_overflow; #[path = "../unsupported/stdio.rs"] pub mod stdio; pub mod thread; diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs index 31197e4accc..f1264130faf 100644 --- a/library/std/src/sys/windows/args.rs +++ b/library/std/src/sys/windows/args.rs @@ -14,10 +14,6 @@ use crate::vec; use core::iter; -pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} - -pub unsafe fn cleanup() {} - pub fn args() -> Args { unsafe { let lp_cmd_line = c::GetCommandLineW(); diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index 973301af2d9..ddb6ac5f55c 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -49,8 +49,17 @@ cfg_if::cfg_if! { } } -#[cfg(not(test))] -pub fn init() {} +// SAFETY: must be called only once during runtime initialization. +// NOTE: this is not guaranteed to run, for example when Rust code is called externally. +pub unsafe fn init(_argc: isize, _argv: *const *const u8) { + stack_overflow::init(); +} + +// SAFETY: must be called only once during runtime cleanup. +// NOTE: this is not guaranteed to run, for example when the program aborts. +pub unsafe fn cleanup() { + net::cleanup(); +} pub fn decode_error_kind(errno: i32) -> ErrorKind { match errno as c::DWORD { diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index ad04afc0b6d..1ad13254c08 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -9,7 +9,7 @@ use crate::sync::Once; use crate::sys; use crate::sys::c; use crate::sys_common::net; -use crate::sys_common::{self, AsInner, FromInner, IntoInner}; +use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; use libc::{c_int, c_long, c_ulong, c_void}; @@ -26,23 +26,28 @@ pub mod netc { pub struct Socket(c::SOCKET); +static INIT: Once = Once::new(); + /// Checks whether the Windows socket interface has been started already, and /// if not, starts it. pub fn init() { - static START: Once = Once::new(); - - START.call_once(|| unsafe { + INIT.call_once(|| unsafe { let mut data: c::WSADATA = mem::zeroed(); let ret = c::WSAStartup( 0x202, // version 2.2 &mut data, ); assert_eq!(ret, 0); + }); +} - let _ = sys_common::at_exit(|| { +pub fn cleanup() { + if INIT.is_completed() { + // only close the socket interface if it has actually been started + unsafe { c::WSACleanup(); - }); - }); + } + } } /// Returns the last error from the Windows socket interface. diff --git a/library/std/src/sys/windows/stack_overflow.rs b/library/std/src/sys/windows/stack_overflow.rs index 187ad4e66c3..39efb778207 100644 --- a/library/std/src/sys/windows/stack_overflow.rs +++ b/library/std/src/sys/windows/stack_overflow.rs @@ -37,5 +37,3 @@ pub unsafe fn init() { // Set the thread stack guarantee for the main thread. let _h = Handler::new(); } - -pub unsafe fn cleanup() {} diff --git a/library/std/src/sys/windows/stack_overflow_uwp.rs b/library/std/src/sys/windows/stack_overflow_uwp.rs index e7236cf359c..afdf7f566ae 100644 --- a/library/std/src/sys/windows/stack_overflow_uwp.rs +++ b/library/std/src/sys/windows/stack_overflow_uwp.rs @@ -9,5 +9,3 @@ impl Handler { } pub unsafe fn init() {} - -pub unsafe fn cleanup() {} |
