html-to-markdown 2.27.2 → 2.27.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +8 -8
- data/ext/html-to-markdown-rb/native/Cargo.toml +1 -1
- data/lib/html_to_markdown/version.rb +1 -1
- data/rust-vendor/getrandom/.cargo-checksum.json +1 -1
- data/rust-vendor/getrandom/.cargo_vcs_info.json +1 -1
- data/rust-vendor/getrandom/CHANGELOG.md +62 -43
- data/rust-vendor/getrandom/Cargo.lock +49 -56
- data/rust-vendor/getrandom/Cargo.toml +2 -2
- data/rust-vendor/getrandom/Cargo.toml.orig +2 -2
- data/rust-vendor/getrandom/src/backends/efi_rng.rs +8 -10
- data/rust-vendor/getrandom/src/backends/getentropy.rs +13 -4
- data/rust-vendor/getrandom/src/backends/linux_android_with_fallback.rs +10 -25
- data/rust-vendor/getrandom/src/backends/netbsd.rs +17 -25
- data/rust-vendor/getrandom/src/backends/rdrand.rs +15 -9
- data/rust-vendor/getrandom/src/backends/rndr.rs +2 -1
- data/rust-vendor/getrandom/src/backends/vxworks.rs +7 -3
- data/rust-vendor/getrandom/src/backends/windows.rs +21 -5
- data/rust-vendor/getrandom/src/utils/lazy_bool.rs +39 -0
- data/rust-vendor/getrandom/src/utils/lazy_ptr.rs +57 -0
- data/rust-vendor/html-to-markdown-rs/Cargo.toml +2 -2
- data/rust-vendor/html-to-markdown-rs/src/converter/text_node.rs +2 -1
- data/rust-vendor/html-to-markdown-rs/tests/issue_216_217_regressions.rs +82 -0
- data/rust-vendor/quote/.cargo-checksum.json +1 -1
- data/rust-vendor/quote/.cargo_vcs_info.json +1 -1
- data/rust-vendor/quote/.github/workflows/ci.yml +2 -2
- data/rust-vendor/quote/Cargo.lock +21 -21
- data/rust-vendor/quote/Cargo.toml +2 -2
- data/rust-vendor/quote/Cargo.toml.orig +2 -2
- data/rust-vendor/quote/README.md +0 -1
- data/rust-vendor/quote/src/lib.rs +1 -1
- data/rust-vendor/quote/src/to_tokens.rs +7 -0
- data/rust-vendor/quote/tests/ui/not-quotable.stderr +1 -1
- data/rust-vendor/quote/tests/ui/not-repeatable.stderr +3 -11
- data/rust-vendor/r-efi/.cargo-checksum.json +1 -1
- data/rust-vendor/r-efi/.cargo_vcs_info.json +1 -1
- data/rust-vendor/r-efi/AUTHORS +1 -0
- data/rust-vendor/r-efi/Cargo.lock +1 -1
- data/rust-vendor/r-efi/Cargo.toml +1 -3
- data/rust-vendor/r-efi/Cargo.toml.orig +1 -5
- data/rust-vendor/r-efi/NEWS.md +16 -0
- data/rust-vendor/r-efi/src/base.rs +1 -1
- data/rust-vendor/r-efi/src/lib.rs +27 -12
- data/rust-vendor/r-efi/src/protocols/absolute_pointer.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/block_io.rs +8 -8
- data/rust-vendor/r-efi/src/protocols/bus_specific_driver_override.rs +2 -2
- data/rust-vendor/r-efi/src/protocols/debug_support.rs +10 -10
- data/rust-vendor/r-efi/src/protocols/debugport.rs +8 -8
- data/rust-vendor/r-efi/src/protocols/decompress.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/device_path_from_text.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/device_path_to_text.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/device_path_utilities.rs +16 -16
- data/rust-vendor/r-efi/src/protocols/disk_io.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/disk_io2.rs +8 -8
- data/rust-vendor/r-efi/src/protocols/driver_binding.rs +6 -6
- data/rust-vendor/r-efi/src/protocols/driver_diagnostics2.rs +2 -2
- data/rust-vendor/r-efi/src/protocols/driver_family_override.rs +2 -2
- data/rust-vendor/r-efi/src/protocols/file.rs +28 -28
- data/rust-vendor/r-efi/src/protocols/graphics_output.rs +6 -6
- data/rust-vendor/r-efi/src/protocols/hii_database.rs +24 -24
- data/rust-vendor/r-efi/src/protocols/hii_font.rs +8 -8
- data/rust-vendor/r-efi/src/protocols/hii_font_ex.rs +10 -10
- data/rust-vendor/r-efi/src/protocols/hii_string.rs +10 -10
- data/rust-vendor/r-efi/src/protocols/ip4.rs +16 -16
- data/rust-vendor/r-efi/src/protocols/ip6.rs +18 -18
- data/rust-vendor/r-efi/src/protocols/load_file.rs +2 -2
- data/rust-vendor/r-efi/src/protocols/loaded_image.rs +2 -2
- data/rust-vendor/r-efi/src/protocols/managed_network.rs +16 -16
- data/rust-vendor/r-efi/src/protocols/memory_attribute.rs +6 -6
- data/rust-vendor/r-efi/src/protocols/mp_services.rs +15 -15
- data/rust-vendor/r-efi/src/protocols/pci_io.rs +26 -26
- data/rust-vendor/r-efi/src/protocols/platform_driver_override.rs +6 -6
- data/rust-vendor/r-efi/src/protocols/rng.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/service_binding.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/shell.rs +81 -81
- data/rust-vendor/r-efi/src/protocols/shell_dynamic_command.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/simple_file_system.rs +2 -2
- data/rust-vendor/r-efi/src/protocols/simple_network.rs +26 -26
- data/rust-vendor/r-efi/src/protocols/simple_text_input.rs +4 -4
- data/rust-vendor/r-efi/src/protocols/simple_text_input_ex.rs +11 -11
- data/rust-vendor/r-efi/src/protocols/simple_text_output.rs +18 -18
- data/rust-vendor/r-efi/src/protocols/tcp4.rs +20 -20
- data/rust-vendor/r-efi/src/protocols/tcp6.rs +18 -18
- data/rust-vendor/r-efi/src/protocols/timestamp.rs +3 -3
- data/rust-vendor/r-efi/src/protocols/udp4.rs +16 -16
- data/rust-vendor/r-efi/src/protocols/udp6.rs +14 -14
- data/rust-vendor/r-efi/src/system.rs +115 -115
- data/rust-vendor/r-efi/src/vendor/intel/console_control.rs +6 -6
- data/rust-vendor/r-efi-5.3.0/.cargo-checksum.json +1 -0
- data/rust-vendor/r-efi-5.3.0/.cargo_vcs_info.json +6 -0
- data/rust-vendor/r-efi-5.3.0/.github/workflows/publish.yml +39 -0
- data/rust-vendor/r-efi-5.3.0/.github/workflows/rust-tests.yml +125 -0
- data/rust-vendor/r-efi-5.3.0/AUTHORS +74 -0
- data/rust-vendor/r-efi-5.3.0/Cargo.lock +16 -0
- data/rust-vendor/r-efi-5.3.0/Cargo.toml +70 -0
- data/rust-vendor/r-efi-5.3.0/Cargo.toml.orig +51 -0
- data/rust-vendor/r-efi-5.3.0/Makefile +85 -0
- data/rust-vendor/r-efi-5.3.0/NEWS.md +301 -0
- data/rust-vendor/r-efi-5.3.0/README.md +99 -0
- data/rust-vendor/r-efi-5.3.0/examples/freestanding.rs +34 -0
- data/rust-vendor/r-efi-5.3.0/examples/gop-query.rs +188 -0
- data/rust-vendor/r-efi-5.3.0/examples/hello-world.rs +55 -0
- data/rust-vendor/r-efi-5.3.0/src/base.rs +993 -0
- data/rust-vendor/r-efi-5.3.0/src/hii.rs +1300 -0
- data/rust-vendor/r-efi-5.3.0/src/lib.rs +182 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/absolute_pointer.rs +69 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/block_io.rs +70 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/bus_specific_driver_override.rs +32 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/debug_support.rs +835 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/debugport.rs +42 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/decompress.rs +37 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/device_path.rs +82 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/device_path_from_text.rs +26 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/device_path_to_text.rs +30 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/device_path_utilities.rs +63 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/disk_io.rs +40 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/disk_io2.rs +58 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/driver_binding.rs +42 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/driver_diagnostics2.rs +38 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/driver_family_override.rs +23 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/file.rs +183 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/graphics_output.rs +103 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/hii_database.rs +299 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/hii_font.rs +87 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/hii_font_ex.rs +107 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/hii_package_list.rs +14 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/hii_string.rs +71 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/ip4.rs +202 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/ip6.rs +264 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/load_file.rs +26 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/load_file2.rs +15 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/loaded_image.rs +39 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/loaded_image_device_path.rs +13 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/managed_network.rs +147 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/memory_attribute.rs +40 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/mp_services.rs +121 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/pci_io.rs +203 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/platform_driver_override.rs +46 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/rng.rs +83 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/service_binding.rs +20 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/shell.rs +295 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/shell_dynamic_command.rs +33 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/shell_parameters.rs +23 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/simple_file_system.rs +26 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/simple_network.rs +196 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/simple_text_input.rs +38 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/simple_text_input_ex.rs +85 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/simple_text_output.rs +86 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/tcp4.rs +224 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/tcp6.rs +202 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/timestamp.rs +32 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/udp4.rs +151 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols/udp6.rs +137 -0
- data/rust-vendor/r-efi-5.3.0/src/protocols.rs +54 -0
- data/rust-vendor/r-efi-5.3.0/src/system.rs +1130 -0
- data/rust-vendor/r-efi-5.3.0/src/vendor/intel/console_control.rs +37 -0
- data/rust-vendor/r-efi-5.3.0/src/vendor.rs +10 -0
- data/rust-vendor/tokio/.cargo-checksum.json +1 -1
- data/rust-vendor/tokio/.cargo_vcs_info.json +1 -1
- data/rust-vendor/tokio/CHANGELOG.md +94 -0
- data/rust-vendor/tokio/Cargo.lock +1549 -0
- data/rust-vendor/tokio/Cargo.toml +96 -83
- data/rust-vendor/tokio/Cargo.toml.orig +7 -7
- data/rust-vendor/tokio/README.md +1 -1
- data/rust-vendor/tokio/src/fs/open_options.rs +4 -1
- data/rust-vendor/tokio/src/fs/read.rs +4 -1
- data/rust-vendor/tokio/src/fs/write.rs +4 -1
- data/rust-vendor/tokio/src/io/async_write.rs +3 -4
- data/rust-vendor/tokio/src/io/poll_evented.rs +23 -1
- data/rust-vendor/tokio/src/io/stderr.rs +15 -1
- data/rust-vendor/tokio/src/io/stdout.rs +14 -0
- data/rust-vendor/tokio/src/io/util/async_write_ext.rs +2 -2
- data/rust-vendor/tokio/src/io/util/write_buf.rs +11 -2
- data/rust-vendor/tokio/src/lib.rs +12 -28
- data/rust-vendor/tokio/src/macros/select.rs +6 -8
- data/rust-vendor/tokio/src/net/tcp/socket.rs +25 -1
- data/rust-vendor/tokio/src/net/tcp/stream.rs +40 -1
- data/rust-vendor/tokio/src/process/unix/pidfd_reaper.rs +1 -41
- data/rust-vendor/tokio/src/runtime/blocking/pool.rs +18 -14
- data/rust-vendor/tokio/src/runtime/builder.rs +10 -4
- data/rust-vendor/tokio/src/runtime/handle.rs +3 -2
- data/rust-vendor/tokio/src/runtime/io/driver/uring.rs +49 -61
- data/rust-vendor/tokio/src/runtime/io/driver.rs +6 -5
- data/rust-vendor/tokio/src/runtime/mod.rs +20 -1
- data/rust-vendor/tokio/src/runtime/runtime.rs +71 -1
- data/rust-vendor/tokio/src/runtime/scheduler/current_thread/mod.rs +24 -8
- data/rust-vendor/tokio/src/runtime/scheduler/multi_thread/worker.rs +5 -0
- data/rust-vendor/tokio/src/runtime/task/core.rs +1 -0
- data/rust-vendor/tokio/src/runtime/task/join.rs +7 -3
- data/rust-vendor/tokio/src/runtime/task/list.rs +5 -3
- data/rust-vendor/tokio/src/runtime/task/mod.rs +0 -5
- data/rust-vendor/tokio/src/runtime/tests/loom_blocking.rs +39 -1
- data/rust-vendor/tokio/src/signal/mod.rs +6 -17
- data/rust-vendor/tokio/src/signal/registry.rs +1 -1
- data/rust-vendor/tokio/src/signal/unix.rs +24 -44
- data/rust-vendor/tokio/src/signal/windows/sys.rs +52 -64
- data/rust-vendor/tokio/src/signal/windows.rs +35 -23
- data/rust-vendor/tokio/src/sync/mpsc/mod.rs +3 -1
- data/rust-vendor/tokio/src/sync/oneshot.rs +13 -0
- data/rust-vendor/tokio/src/sync/rwlock.rs +4 -5
- data/rust-vendor/tokio/src/sync/tests/loom_oneshot.rs +27 -1
- data/rust-vendor/tokio/src/task/blocking.rs +16 -1
- data/rust-vendor/tokio/src/task/builder.rs +2 -2
- data/rust-vendor/tokio/src/task/mod.rs +1 -1
- data/rust-vendor/tokio/src/task/spawn.rs +8 -3
- data/rust-vendor/tokio/src/task/yield_now.rs +13 -23
- data/rust-vendor/tokio/src/time/clock.rs +62 -0
- data/rust-vendor/tokio/src/util/memchr.rs +32 -4
- data/rust-vendor/tokio/src/util/sharded_list.rs +6 -4
- data/rust-vendor/tokio/tests/fs_link.rs +54 -0
- data/rust-vendor/tokio/tests/io_async_fd_memory_leak.rs +209 -0
- data/rust-vendor/tokio/tests/io_write_buf.rs +56 -0
- data/rust-vendor/tokio/tests/process_issue_7144.rs +8 -0
- data/rust-vendor/tokio/tests/rt_basic.rs +41 -0
- data/rust-vendor/tokio/tests/rt_common_before_park.rs +92 -0
- data/rust-vendor/tokio/tests/rt_metrics.rs +1 -1
- data/rust-vendor/tokio/tests/rt_panic.rs +12 -0
- data/rust-vendor/tokio/tests/rt_shutdown_err.rs +82 -0
- data/rust-vendor/tokio/tests/rt_threaded.rs +49 -1
- data/rust-vendor/tokio/tests/rt_unstable_metrics.rs +32 -0
- data/rust-vendor/tokio/tests/tcp_connect.rs +2 -3
- data/rust-vendor/tokio/tests/tcp_shutdown.rs +1 -3
- data/rust-vendor/tokio/tests/tcp_socket.rs +3 -4
- data/rust-vendor/tokio/tests/tcp_stream.rs +3 -0
- metadata +78 -3
- data/rust-vendor/getrandom/src/utils/lazy.rs +0 -64
|
@@ -1256,9 +1256,10 @@ impl TcpStream {
|
|
|
1256
1256
|
/// Reads the linger duration for this socket by getting the `SO_LINGER`
|
|
1257
1257
|
/// option.
|
|
1258
1258
|
///
|
|
1259
|
-
/// For more information about this option, see [`set_linger`].
|
|
1259
|
+
/// For more information about this option, see [`set_zero_linger`] and [`set_linger`].
|
|
1260
1260
|
///
|
|
1261
1261
|
/// [`set_linger`]: TcpStream::set_linger
|
|
1262
|
+
/// [`set_zero_linger`]: TcpStream::set_zero_linger
|
|
1262
1263
|
///
|
|
1263
1264
|
/// # Examples
|
|
1264
1265
|
///
|
|
@@ -1295,6 +1296,11 @@ impl TcpStream {
|
|
|
1295
1296
|
/// >
|
|
1296
1297
|
/// > From [The ultimate `SO_LINGER` page, or: why is my tcp not reliable](https://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable)
|
|
1297
1298
|
///
|
|
1299
|
+
/// Although this method is deprecated, it will not be removed from Tokio.
|
|
1300
|
+
///
|
|
1301
|
+
/// Note that the special case of setting `SO_LINGER` to zero does not lead to blocking.
|
|
1302
|
+
/// Tokio provides [`set_zero_linger`](Self::set_zero_linger) for this purpose.
|
|
1303
|
+
///
|
|
1298
1304
|
/// # Examples
|
|
1299
1305
|
///
|
|
1300
1306
|
/// ```no_run
|
|
@@ -1312,6 +1318,39 @@ impl TcpStream {
|
|
|
1312
1318
|
pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
|
|
1313
1319
|
socket2::SockRef::from(self).set_linger(dur)
|
|
1314
1320
|
}
|
|
1321
|
+
|
|
1322
|
+
/// Sets a linger duration of zero on this socket by setting the `SO_LINGER` option.
|
|
1323
|
+
///
|
|
1324
|
+
/// This causes the connection to be forcefully aborted ("abortive close") when the socket
|
|
1325
|
+
/// is dropped or closed. Instead of the normal TCP shutdown handshake (`FIN`/`ACK`), a TCP
|
|
1326
|
+
/// `RST` (reset) segment is sent to the peer, and the socket immediately discards any
|
|
1327
|
+
/// unsent data residing in the socket send buffer. This prevents the socket from entering
|
|
1328
|
+
/// the `TIME_WAIT` state after closing it.
|
|
1329
|
+
///
|
|
1330
|
+
/// This is a destructive action. Any data currently buffered by the OS but not yet
|
|
1331
|
+
/// transmitted will be lost. The peer will likely receive a "Connection Reset" error
|
|
1332
|
+
/// rather than a clean end-of-stream.
|
|
1333
|
+
///
|
|
1334
|
+
/// See the documentation for [`set_linger`](Self::set_linger) for additional details on
|
|
1335
|
+
/// how `SO_LINGER` works.
|
|
1336
|
+
///
|
|
1337
|
+
/// # Examples
|
|
1338
|
+
///
|
|
1339
|
+
/// ```no_run
|
|
1340
|
+
/// use std::time::Duration;
|
|
1341
|
+
/// use tokio::net::TcpStream;
|
|
1342
|
+
///
|
|
1343
|
+
/// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
|
|
1344
|
+
/// let stream = TcpStream::connect("127.0.0.1:8080").await?;
|
|
1345
|
+
///
|
|
1346
|
+
/// stream.set_zero_linger()?;
|
|
1347
|
+
/// assert_eq!(stream.linger()?, Some(Duration::ZERO));
|
|
1348
|
+
/// # Ok(())
|
|
1349
|
+
/// # }
|
|
1350
|
+
/// ```
|
|
1351
|
+
pub fn set_zero_linger(&self) -> io::Result<()> {
|
|
1352
|
+
socket2::SockRef::from(self).set_linger(Some(Duration::ZERO))
|
|
1353
|
+
}
|
|
1315
1354
|
}
|
|
1316
1355
|
|
|
1317
1356
|
/// Gets the value of the `IP_TTL` option for this socket.
|
|
@@ -4,7 +4,6 @@ use crate::{
|
|
|
4
4
|
imp::{orphan::Wait, OrphanQueue},
|
|
5
5
|
kill::Kill,
|
|
6
6
|
},
|
|
7
|
-
util::error::RUNTIME_SHUTTING_DOWN_ERROR,
|
|
8
7
|
};
|
|
9
8
|
|
|
10
9
|
use libc::{syscall, SYS_pidfd_open, ENOSYS, PIDFD_NONBLOCK};
|
|
@@ -95,45 +94,6 @@ where
|
|
|
95
94
|
pidfd: PollEvented<Pidfd>,
|
|
96
95
|
}
|
|
97
96
|
|
|
98
|
-
fn display_eq(d: impl std::fmt::Display, s: &str) -> bool {
|
|
99
|
-
use std::fmt::Write;
|
|
100
|
-
|
|
101
|
-
struct FormatEq<'r> {
|
|
102
|
-
remainder: &'r str,
|
|
103
|
-
unequal: bool,
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
impl<'r> Write for FormatEq<'r> {
|
|
107
|
-
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
|
108
|
-
if !self.unequal {
|
|
109
|
-
if let Some(new_remainder) = self.remainder.strip_prefix(s) {
|
|
110
|
-
self.remainder = new_remainder;
|
|
111
|
-
} else {
|
|
112
|
-
self.unequal = true;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
Ok(())
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
let mut fmt_eq = FormatEq {
|
|
120
|
-
remainder: s,
|
|
121
|
-
unequal: false,
|
|
122
|
-
};
|
|
123
|
-
let _ = write!(fmt_eq, "{d}");
|
|
124
|
-
fmt_eq.remainder.is_empty() && !fmt_eq.unequal
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
fn is_rt_shutdown_err(err: &io::Error) -> bool {
|
|
128
|
-
if let Some(inner) = err.get_ref() {
|
|
129
|
-
err.kind() == io::ErrorKind::Other
|
|
130
|
-
&& inner.source().is_none()
|
|
131
|
-
&& display_eq(inner, RUNTIME_SHUTTING_DOWN_ERROR)
|
|
132
|
-
} else {
|
|
133
|
-
false
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
97
|
impl<W> Future for PidfdReaperInner<W>
|
|
138
98
|
where
|
|
139
99
|
W: Wait + Unpin,
|
|
@@ -150,7 +110,7 @@ where
|
|
|
150
110
|
}
|
|
151
111
|
this.pidfd.registration().clear_readiness(evt);
|
|
152
112
|
}
|
|
153
|
-
Poll::Ready(Err(err)) if is_rt_shutdown_err(&err) => {}
|
|
113
|
+
Poll::Ready(Err(err)) if crate::runtime::is_rt_shutdown_err(&err) => {}
|
|
154
114
|
Poll::Ready(Err(err)) => return Poll::Ready(Err(err)),
|
|
155
115
|
Poll::Pending => return Poll::Pending,
|
|
156
116
|
};
|
|
@@ -507,6 +507,8 @@ impl Inner {
|
|
|
507
507
|
|
|
508
508
|
let mut shared = self.shared.lock();
|
|
509
509
|
let mut join_on_thread = None;
|
|
510
|
+
// is this thread currently counted in `num_idle_threads`?
|
|
511
|
+
let mut is_counted_idle;
|
|
510
512
|
|
|
511
513
|
'main: loop {
|
|
512
514
|
// BUSY
|
|
@@ -520,6 +522,8 @@ impl Inner {
|
|
|
520
522
|
|
|
521
523
|
// IDLE
|
|
522
524
|
self.metrics.inc_num_idle_threads();
|
|
525
|
+
// mark this thread as currently counted in `num_idle_threads`.
|
|
526
|
+
is_counted_idle = true;
|
|
523
527
|
|
|
524
528
|
while !shared.shutdown {
|
|
525
529
|
let lock_result = self.condvar.wait_timeout(shared, self.keep_alive).unwrap();
|
|
@@ -532,6 +536,9 @@ impl Inner {
|
|
|
532
536
|
// acknowledge it by decrementing the counter
|
|
533
537
|
// and transition to the BUSY state.
|
|
534
538
|
shared.num_notify -= 1;
|
|
539
|
+
// since this is a legitimate wakeup,
|
|
540
|
+
// the `Spawner::spawn_task` has already decremented `num_idle_threads`.
|
|
541
|
+
is_counted_idle = false;
|
|
535
542
|
break;
|
|
536
543
|
}
|
|
537
544
|
|
|
@@ -561,12 +568,6 @@ impl Inner {
|
|
|
561
568
|
shared = self.shared.lock();
|
|
562
569
|
}
|
|
563
570
|
|
|
564
|
-
// Work was produced, and we "took" it (by decrementing num_notify).
|
|
565
|
-
// This means that num_idle was decremented once for our wakeup.
|
|
566
|
-
// But, since we are exiting, we need to "undo" that, as we'll stay idle.
|
|
567
|
-
self.metrics.inc_num_idle_threads();
|
|
568
|
-
// NOTE: Technically we should also do num_notify++ and notify again,
|
|
569
|
-
// but since we're shutting down anyway, that won't be necessary.
|
|
570
571
|
break;
|
|
571
572
|
}
|
|
572
573
|
}
|
|
@@ -574,14 +575,17 @@ impl Inner {
|
|
|
574
575
|
// Thread exit
|
|
575
576
|
self.metrics.dec_num_threads();
|
|
576
577
|
|
|
577
|
-
//
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
prev_idle
|
|
583
|
-
|
|
584
|
-
|
|
578
|
+
// Is this thread currently counted in `num_idle_threads`?
|
|
579
|
+
if is_counted_idle {
|
|
580
|
+
// `num_idle_threads` should now be tracked exactly, panic
|
|
581
|
+
// with a descriptive message if it is not the
|
|
582
|
+
// case.
|
|
583
|
+
let prev_idle = self.metrics.dec_num_idle_threads();
|
|
584
|
+
assert_ne!(
|
|
585
|
+
prev_idle, 0,
|
|
586
|
+
"`num_idle_threads` underflowed on thread exit"
|
|
587
|
+
);
|
|
588
|
+
}
|
|
585
589
|
|
|
586
590
|
if shared.shutdown && self.metrics.num_threads() == 0 {
|
|
587
591
|
self.condvar.notify_one();
|
|
@@ -288,7 +288,7 @@ impl Builder {
|
|
|
288
288
|
max_blocking_threads: 512,
|
|
289
289
|
|
|
290
290
|
// Default thread name
|
|
291
|
-
thread_name: std::sync::Arc::new(|| "tokio-
|
|
291
|
+
thread_name: std::sync::Arc::new(|| "tokio-rt-worker".into()),
|
|
292
292
|
|
|
293
293
|
// Do not set a stack size by default
|
|
294
294
|
thread_stack_size: None,
|
|
@@ -516,7 +516,7 @@ impl Builder {
|
|
|
516
516
|
|
|
517
517
|
/// Sets name of threads spawned by the `Runtime`'s thread pool.
|
|
518
518
|
///
|
|
519
|
-
/// The default name is "tokio-
|
|
519
|
+
/// The default name is "tokio-rt-worker".
|
|
520
520
|
///
|
|
521
521
|
/// # Examples
|
|
522
522
|
///
|
|
@@ -540,7 +540,7 @@ impl Builder {
|
|
|
540
540
|
|
|
541
541
|
/// Sets a function used to generate the name of threads spawned by the `Runtime`'s thread pool.
|
|
542
542
|
///
|
|
543
|
-
/// The default name fn is `|| "tokio-
|
|
543
|
+
/// The default name fn is `|| "tokio-rt-worker".into()`.
|
|
544
544
|
///
|
|
545
545
|
/// # Examples
|
|
546
546
|
///
|
|
@@ -1116,13 +1116,17 @@ impl Builder {
|
|
|
1116
1116
|
/// Setting the event interval determines the effective "priority" of delivering
|
|
1117
1117
|
/// these external events (which may wake up additional tasks), compared to
|
|
1118
1118
|
/// executing tasks that are currently ready to run. A smaller value is useful
|
|
1119
|
-
/// when tasks frequently spend a long time in polling, or
|
|
1119
|
+
/// when tasks frequently spend a long time in polling, or infrequently yield,
|
|
1120
1120
|
/// which can result in overly long delays picking up I/O events. Conversely,
|
|
1121
1121
|
/// picking up new events requires extra synchronization and syscall overhead,
|
|
1122
1122
|
/// so if tasks generally complete their polling quickly, a higher event interval
|
|
1123
1123
|
/// will minimize that overhead while still keeping the scheduler responsive to
|
|
1124
1124
|
/// events.
|
|
1125
1125
|
///
|
|
1126
|
+
/// # Panics
|
|
1127
|
+
///
|
|
1128
|
+
/// This function will panic if 0 is passed as an argument.
|
|
1129
|
+
///
|
|
1126
1130
|
/// # Examples
|
|
1127
1131
|
///
|
|
1128
1132
|
/// ```
|
|
@@ -1136,7 +1140,9 @@ impl Builder {
|
|
|
1136
1140
|
/// # }
|
|
1137
1141
|
/// # }
|
|
1138
1142
|
/// ```
|
|
1143
|
+
#[track_caller]
|
|
1139
1144
|
pub fn event_interval(&mut self, val: u32) -> &mut Self {
|
|
1145
|
+
assert!(val > 0, "event_interval must be greater than 0");
|
|
1140
1146
|
self.event_interval = val;
|
|
1141
1147
|
self
|
|
1142
1148
|
}
|
|
@@ -166,11 +166,12 @@ impl Handle {
|
|
|
166
166
|
///
|
|
167
167
|
/// The provided future will start running in the background immediately
|
|
168
168
|
/// when `spawn` is called, even if you don't await the returned
|
|
169
|
-
/// `JoinHandle
|
|
169
|
+
/// `JoinHandle` (assuming that the runtime [is running][running-runtime]).
|
|
170
170
|
///
|
|
171
171
|
/// See [module level][mod] documentation for more details.
|
|
172
172
|
///
|
|
173
173
|
/// [mod]: index.html
|
|
174
|
+
/// [running-runtime]: index.html#driving-the-runtime
|
|
174
175
|
///
|
|
175
176
|
/// # Examples
|
|
176
177
|
///
|
|
@@ -560,7 +561,7 @@ cfg_taskdump! {
|
|
|
560
561
|
/// You can do this by setting the `RUSTFLAGS` environment variable
|
|
561
562
|
/// before invoking `cargo`; e.g.:
|
|
562
563
|
/// ```bash
|
|
563
|
-
/// RUSTFLAGS="--cfg tokio_unstable cargo run --example dump
|
|
564
|
+
/// RUSTFLAGS="--cfg tokio_unstable" cargo run --example dump
|
|
564
565
|
/// ```
|
|
565
566
|
///
|
|
566
567
|
/// Or by [configuring][cargo-config] `rustflags` in
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
use io_uring::{squeue::Entry, IoUring};
|
|
1
|
+
use io_uring::{squeue::Entry, IoUring, Probe};
|
|
2
2
|
use mio::unix::SourceFd;
|
|
3
3
|
use slab::Slab;
|
|
4
4
|
|
|
5
|
-
use crate::loom::sync::atomic::Ordering;
|
|
6
5
|
use crate::runtime::driver::op::{Cancellable, Lifecycle};
|
|
7
6
|
use crate::{io::Interest, loom::sync::Mutex};
|
|
8
7
|
|
|
@@ -13,29 +12,6 @@ use std::{io, mem, task::Waker};
|
|
|
13
12
|
|
|
14
13
|
const DEFAULT_RING_SIZE: u32 = 256;
|
|
15
14
|
|
|
16
|
-
#[repr(usize)]
|
|
17
|
-
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
|
18
|
-
enum State {
|
|
19
|
-
Uninitialized = 0,
|
|
20
|
-
Initialized = 1,
|
|
21
|
-
Unsupported = 2,
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
impl State {
|
|
25
|
-
fn as_usize(&self) -> usize {
|
|
26
|
-
*self as usize
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
fn from_usize(value: usize) -> Self {
|
|
30
|
-
match value {
|
|
31
|
-
0 => State::Uninitialized,
|
|
32
|
-
1 => State::Initialized,
|
|
33
|
-
2 => State::Unsupported,
|
|
34
|
-
_ => unreachable!("invalid Uring state: {}", value),
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
15
|
pub(crate) struct UringContext {
|
|
40
16
|
pub(crate) uring: Option<io_uring::IoUring>,
|
|
41
17
|
pub(crate) ops: slab::Slab<Lifecycle>,
|
|
@@ -62,13 +38,24 @@ impl UringContext {
|
|
|
62
38
|
///
|
|
63
39
|
/// If the machine doesn't support io_uring, then this will return an
|
|
64
40
|
/// `ENOSYS` error.
|
|
65
|
-
pub(crate) fn try_init(&mut self) -> io::Result<bool> {
|
|
41
|
+
pub(crate) fn try_init(&mut self, probe: &mut Probe) -> io::Result<bool> {
|
|
66
42
|
if self.uring.is_some() {
|
|
67
43
|
// Already initialized.
|
|
68
44
|
return Ok(false);
|
|
69
45
|
}
|
|
70
46
|
|
|
71
|
-
|
|
47
|
+
let uring = IoUring::new(DEFAULT_RING_SIZE)?;
|
|
48
|
+
|
|
49
|
+
match uring.submitter().register_probe(probe) {
|
|
50
|
+
Ok(_) => {}
|
|
51
|
+
Err(e) if e.raw_os_error() == Some(libc::EINVAL) => {
|
|
52
|
+
// The kernel does not support IORING_REGISTER_PROBE.
|
|
53
|
+
return Err(io::Error::from_raw_os_error(libc::ENOSYS));
|
|
54
|
+
}
|
|
55
|
+
Err(e) => return Err(e),
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
self.uring.replace(uring);
|
|
72
59
|
|
|
73
60
|
Ok(true)
|
|
74
61
|
}
|
|
@@ -177,42 +164,46 @@ impl Handle {
|
|
|
177
164
|
&self.uring_context
|
|
178
165
|
}
|
|
179
166
|
|
|
180
|
-
fn set_uring_state(&self, state: State) {
|
|
181
|
-
self.uring_state.store(state.as_usize(), Ordering::Release);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
167
|
/// Check if the io_uring context is initialized. If not, it will try to initialize it.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
Ok(
|
|
168
|
+
/// Then, check if the provided opcode is supported.
|
|
169
|
+
///
|
|
170
|
+
/// If both the context initialization succeeds and the opcode is supported,
|
|
171
|
+
/// this returns `Ok(true)`.
|
|
172
|
+
/// If either io_uring is unsupported or the opcode is unsupported,
|
|
173
|
+
/// this returns `Ok(false)`.
|
|
174
|
+
/// An error is returned if an io_uring syscall returns an unexpected error value.
|
|
175
|
+
///
|
|
176
|
+
/// TODO: This would like to be a synchronous function,
|
|
177
|
+
/// but we require `OnceLock::get_or_try_init`.
|
|
178
|
+
/// <https://github.com/rust-lang/rust/issues/109737>
|
|
179
|
+
pub(crate) async fn check_and_init(&self, opcode: u8) -> io::Result<bool> {
|
|
180
|
+
let probe = self
|
|
181
|
+
.uring_probe
|
|
182
|
+
.get_or_try_init(|| async {
|
|
183
|
+
let mut probe = Probe::new();
|
|
184
|
+
match self.try_init(&mut probe) {
|
|
185
|
+
Ok(()) => Ok(Some(probe)),
|
|
186
|
+
// If the system doesn't support io_uring, we set the probe to `None`.
|
|
187
|
+
Err(e) if e.raw_os_error() == Some(libc::ENOSYS) => Ok(None),
|
|
188
|
+
// If we get EPERM, io-uring syscalls may be blocked (for example, by seccomp).
|
|
189
|
+
// In this case, we try to fall back to spawn_blocking for this and future operations.
|
|
190
|
+
// See also: https://github.com/tokio-rs/tokio/issues/7691
|
|
191
|
+
Err(e) if e.raw_os_error() == Some(libc::EPERM) => Ok(None),
|
|
192
|
+
// For other system errors, we just return it.
|
|
193
|
+
Err(e) => Err(e),
|
|
203
194
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
195
|
+
})
|
|
196
|
+
.await?;
|
|
197
|
+
|
|
198
|
+
Ok(probe
|
|
199
|
+
.as_ref()
|
|
200
|
+
.is_some_and(|probe| probe.is_supported(opcode)))
|
|
210
201
|
}
|
|
211
202
|
|
|
212
203
|
/// Initialize the io_uring context if it hasn't been initialized yet.
|
|
213
|
-
fn try_init(&self) -> io::Result<()> {
|
|
204
|
+
fn try_init(&self, probe: &mut Probe) -> io::Result<()> {
|
|
214
205
|
let mut guard = self.get_uring().lock();
|
|
215
|
-
if guard.try_init()? {
|
|
206
|
+
if guard.try_init(probe)? {
|
|
216
207
|
self.add_uring_source(guard.ring().as_raw_fd())?;
|
|
217
208
|
}
|
|
218
209
|
|
|
@@ -230,10 +221,7 @@ impl Handle {
|
|
|
230
221
|
/// Callers must ensure that parameters of the entry (such as buffer) are valid and will
|
|
231
222
|
/// be valid for the entire duration of the operation, otherwise it may cause memory problems.
|
|
232
223
|
pub(crate) unsafe fn register_op(&self, entry: Entry, waker: Waker) -> io::Result<usize> {
|
|
233
|
-
|
|
234
|
-
if !self.check_and_init()? {
|
|
235
|
-
return Err(io::Error::from_raw_os_error(libc::ENOSYS));
|
|
236
|
-
}
|
|
224
|
+
assert!(self.uring_probe.initialized());
|
|
237
225
|
|
|
238
226
|
// Uring is initialized.
|
|
239
227
|
|
|
@@ -5,7 +5,7 @@ cfg_signal_internal_and_unix! {
|
|
|
5
5
|
cfg_io_uring! {
|
|
6
6
|
mod uring;
|
|
7
7
|
use uring::UringContext;
|
|
8
|
-
use crate::
|
|
8
|
+
use crate::sync::OnceCell;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
use crate::io::interest::Interest;
|
|
@@ -67,7 +67,7 @@ pub(crate) struct Handle {
|
|
|
67
67
|
feature = "fs",
|
|
68
68
|
target_os = "linux",
|
|
69
69
|
))]
|
|
70
|
-
pub(crate)
|
|
70
|
+
pub(crate) uring_probe: OnceCell<Option<io_uring::Probe>>,
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
#[derive(Debug)]
|
|
@@ -150,7 +150,7 @@ impl Driver {
|
|
|
150
150
|
feature = "fs",
|
|
151
151
|
target_os = "linux",
|
|
152
152
|
))]
|
|
153
|
-
|
|
153
|
+
uring_probe: OnceCell::new(),
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
Ok((driver, handle))
|
|
@@ -296,7 +296,8 @@ impl Handle {
|
|
|
296
296
|
source: &mut impl Source,
|
|
297
297
|
) -> io::Result<()> {
|
|
298
298
|
// Deregister the source with the OS poller **first**
|
|
299
|
-
|
|
299
|
+
// Cleanup ALWAYS happens
|
|
300
|
+
let os_result = self.registry.deregister(source);
|
|
300
301
|
|
|
301
302
|
if self
|
|
302
303
|
.registrations
|
|
@@ -307,7 +308,7 @@ impl Handle {
|
|
|
307
308
|
|
|
308
309
|
self.metrics.dec_fd_count();
|
|
309
310
|
|
|
310
|
-
|
|
311
|
+
os_result // Return error after cleanup
|
|
311
312
|
}
|
|
312
313
|
|
|
313
314
|
fn release_pending_registrations(&self) {
|
|
@@ -205,6 +205,25 @@
|
|
|
205
205
|
//! This is done with [`Builder::enable_io`] and [`Builder::enable_time`]. As a
|
|
206
206
|
//! shorthand, [`Builder::enable_all`] enables both resource drivers.
|
|
207
207
|
//!
|
|
208
|
+
//! ## Driving the runtime
|
|
209
|
+
//!
|
|
210
|
+
//! A Tokio runtime can only execute tasks if the runtime is running. Normally
|
|
211
|
+
//! this is not an issue as the default configuration of a runtime is always running,
|
|
212
|
+
//! but alternate configurations such as the current-thread runtime require that
|
|
213
|
+
//! [`Runtime::block_on`] is called.
|
|
214
|
+
//!
|
|
215
|
+
//! - A multi-threaded runtime is always running because it spawns its own worker
|
|
216
|
+
//! threads.
|
|
217
|
+
//! - A current-thread runtime does not spawn any worker threads, so it can only
|
|
218
|
+
//! execute tasks when you provide a thread by calling [`Runtime::block_on`].
|
|
219
|
+
//! - A [`LocalSet`](crate::task::LocalSet) only executes local tasks spawned on
|
|
220
|
+
//! it when the `LocalSet` is `.awaited` or otherwise driven using one of its
|
|
221
|
+
//! methods for this purpose.
|
|
222
|
+
//!
|
|
223
|
+
//! Please be aware that [`Handle::block_on`] does not drive the runtime.
|
|
224
|
+
//! There must be at least one call to [`Runtime::block_on`] when using the current
|
|
225
|
+
//! thread runtime. [`Handle::block_on`] is not enough.
|
|
226
|
+
//!
|
|
208
227
|
//! ## Lifetime of spawned threads
|
|
209
228
|
//!
|
|
210
229
|
//! The runtime may spawn threads depending on its configuration and usage. The
|
|
@@ -569,7 +588,7 @@ cfg_rt! {
|
|
|
569
588
|
pub use handle::{EnterGuard, Handle, TryCurrentError};
|
|
570
589
|
|
|
571
590
|
mod runtime;
|
|
572
|
-
pub use runtime::{Runtime, RuntimeFlavor};
|
|
591
|
+
pub use runtime::{Runtime, RuntimeFlavor, is_rt_shutdown_err};
|
|
573
592
|
|
|
574
593
|
mod id;
|
|
575
594
|
pub use id::Id;
|
|
@@ -3,9 +3,11 @@ use crate::runtime::blocking::BlockingPool;
|
|
|
3
3
|
use crate::runtime::scheduler::CurrentThread;
|
|
4
4
|
use crate::runtime::{context, EnterGuard, Handle};
|
|
5
5
|
use crate::task::JoinHandle;
|
|
6
|
+
use crate::util::error::RUNTIME_SHUTTING_DOWN_ERROR;
|
|
6
7
|
use crate::util::trace::SpawnMeta;
|
|
7
8
|
|
|
8
9
|
use std::future::Future;
|
|
10
|
+
use std::io;
|
|
9
11
|
use std::mem;
|
|
10
12
|
use std::time::Duration;
|
|
11
13
|
|
|
@@ -208,11 +210,12 @@ impl Runtime {
|
|
|
208
210
|
///
|
|
209
211
|
/// The provided future will start running in the background immediately
|
|
210
212
|
/// when `spawn` is called, even if you don't await the returned
|
|
211
|
-
/// `JoinHandle
|
|
213
|
+
/// `JoinHandle` (assuming that the runtime [is running][running-runtime]).
|
|
212
214
|
///
|
|
213
215
|
/// See [module level][mod] documentation for more details.
|
|
214
216
|
///
|
|
215
217
|
/// [mod]: index.html
|
|
218
|
+
/// [running-runtime]: index.html#driving-the-runtime
|
|
216
219
|
///
|
|
217
220
|
/// # Examples
|
|
218
221
|
///
|
|
@@ -513,3 +516,70 @@ impl Drop for Runtime {
|
|
|
513
516
|
impl std::panic::UnwindSafe for Runtime {}
|
|
514
517
|
|
|
515
518
|
impl std::panic::RefUnwindSafe for Runtime {}
|
|
519
|
+
|
|
520
|
+
fn display_eq(d: impl std::fmt::Display, s: &str) -> bool {
|
|
521
|
+
use std::fmt::Write;
|
|
522
|
+
|
|
523
|
+
struct FormatEq<'r> {
|
|
524
|
+
remainder: &'r str,
|
|
525
|
+
unequal: bool,
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
impl<'r> Write for FormatEq<'r> {
|
|
529
|
+
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
|
530
|
+
if !self.unequal {
|
|
531
|
+
if let Some(new_remainder) = self.remainder.strip_prefix(s) {
|
|
532
|
+
self.remainder = new_remainder;
|
|
533
|
+
} else {
|
|
534
|
+
self.unequal = true;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
Ok(())
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
let mut fmt_eq = FormatEq {
|
|
542
|
+
remainder: s,
|
|
543
|
+
unequal: false,
|
|
544
|
+
};
|
|
545
|
+
let _ = write!(fmt_eq, "{d}");
|
|
546
|
+
fmt_eq.remainder.is_empty() && !fmt_eq.unequal
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/// Checks whether the given error was emitted by Tokio when shutting down its runtime.
|
|
550
|
+
///
|
|
551
|
+
/// # Examples
|
|
552
|
+
///
|
|
553
|
+
/// ```
|
|
554
|
+
/// # #[cfg(not(target_family = "wasm"))]
|
|
555
|
+
/// # {
|
|
556
|
+
/// use tokio::runtime::Runtime;
|
|
557
|
+
/// use tokio::net::TcpListener;
|
|
558
|
+
///
|
|
559
|
+
/// fn main() {
|
|
560
|
+
/// let rt1 = Runtime::new().unwrap();
|
|
561
|
+
/// let rt2 = Runtime::new().unwrap();
|
|
562
|
+
///
|
|
563
|
+
/// let listener = rt1.block_on(async {
|
|
564
|
+
/// TcpListener::bind("127.0.0.1:0").await.unwrap()
|
|
565
|
+
/// });
|
|
566
|
+
///
|
|
567
|
+
/// drop(rt1);
|
|
568
|
+
///
|
|
569
|
+
/// rt2.block_on(async {
|
|
570
|
+
/// let res = listener.accept().await;
|
|
571
|
+
/// assert!(res.is_err());
|
|
572
|
+
/// assert!(tokio::runtime::is_rt_shutdown_err(res.as_ref().unwrap_err()));
|
|
573
|
+
/// });
|
|
574
|
+
/// }
|
|
575
|
+
/// # }
|
|
576
|
+
/// ```
|
|
577
|
+
pub fn is_rt_shutdown_err(err: &io::Error) -> bool {
|
|
578
|
+
if let Some(inner) = err.get_ref() {
|
|
579
|
+
err.kind() == io::ErrorKind::Other
|
|
580
|
+
&& inner.source().is_none()
|
|
581
|
+
&& display_eq(inner, RUNTIME_SHUTTING_DOWN_ERROR)
|
|
582
|
+
} else {
|
|
583
|
+
false
|
|
584
|
+
}
|
|
585
|
+
}
|