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.
Files changed (226) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +8 -8
  3. data/ext/html-to-markdown-rb/native/Cargo.toml +1 -1
  4. data/lib/html_to_markdown/version.rb +1 -1
  5. data/rust-vendor/getrandom/.cargo-checksum.json +1 -1
  6. data/rust-vendor/getrandom/.cargo_vcs_info.json +1 -1
  7. data/rust-vendor/getrandom/CHANGELOG.md +62 -43
  8. data/rust-vendor/getrandom/Cargo.lock +49 -56
  9. data/rust-vendor/getrandom/Cargo.toml +2 -2
  10. data/rust-vendor/getrandom/Cargo.toml.orig +2 -2
  11. data/rust-vendor/getrandom/src/backends/efi_rng.rs +8 -10
  12. data/rust-vendor/getrandom/src/backends/getentropy.rs +13 -4
  13. data/rust-vendor/getrandom/src/backends/linux_android_with_fallback.rs +10 -25
  14. data/rust-vendor/getrandom/src/backends/netbsd.rs +17 -25
  15. data/rust-vendor/getrandom/src/backends/rdrand.rs +15 -9
  16. data/rust-vendor/getrandom/src/backends/rndr.rs +2 -1
  17. data/rust-vendor/getrandom/src/backends/vxworks.rs +7 -3
  18. data/rust-vendor/getrandom/src/backends/windows.rs +21 -5
  19. data/rust-vendor/getrandom/src/utils/lazy_bool.rs +39 -0
  20. data/rust-vendor/getrandom/src/utils/lazy_ptr.rs +57 -0
  21. data/rust-vendor/html-to-markdown-rs/Cargo.toml +2 -2
  22. data/rust-vendor/html-to-markdown-rs/src/converter/text_node.rs +2 -1
  23. data/rust-vendor/html-to-markdown-rs/tests/issue_216_217_regressions.rs +82 -0
  24. data/rust-vendor/quote/.cargo-checksum.json +1 -1
  25. data/rust-vendor/quote/.cargo_vcs_info.json +1 -1
  26. data/rust-vendor/quote/.github/workflows/ci.yml +2 -2
  27. data/rust-vendor/quote/Cargo.lock +21 -21
  28. data/rust-vendor/quote/Cargo.toml +2 -2
  29. data/rust-vendor/quote/Cargo.toml.orig +2 -2
  30. data/rust-vendor/quote/README.md +0 -1
  31. data/rust-vendor/quote/src/lib.rs +1 -1
  32. data/rust-vendor/quote/src/to_tokens.rs +7 -0
  33. data/rust-vendor/quote/tests/ui/not-quotable.stderr +1 -1
  34. data/rust-vendor/quote/tests/ui/not-repeatable.stderr +3 -11
  35. data/rust-vendor/r-efi/.cargo-checksum.json +1 -1
  36. data/rust-vendor/r-efi/.cargo_vcs_info.json +1 -1
  37. data/rust-vendor/r-efi/AUTHORS +1 -0
  38. data/rust-vendor/r-efi/Cargo.lock +1 -1
  39. data/rust-vendor/r-efi/Cargo.toml +1 -3
  40. data/rust-vendor/r-efi/Cargo.toml.orig +1 -5
  41. data/rust-vendor/r-efi/NEWS.md +16 -0
  42. data/rust-vendor/r-efi/src/base.rs +1 -1
  43. data/rust-vendor/r-efi/src/lib.rs +27 -12
  44. data/rust-vendor/r-efi/src/protocols/absolute_pointer.rs +4 -4
  45. data/rust-vendor/r-efi/src/protocols/block_io.rs +8 -8
  46. data/rust-vendor/r-efi/src/protocols/bus_specific_driver_override.rs +2 -2
  47. data/rust-vendor/r-efi/src/protocols/debug_support.rs +10 -10
  48. data/rust-vendor/r-efi/src/protocols/debugport.rs +8 -8
  49. data/rust-vendor/r-efi/src/protocols/decompress.rs +4 -4
  50. data/rust-vendor/r-efi/src/protocols/device_path_from_text.rs +4 -4
  51. data/rust-vendor/r-efi/src/protocols/device_path_to_text.rs +4 -4
  52. data/rust-vendor/r-efi/src/protocols/device_path_utilities.rs +16 -16
  53. data/rust-vendor/r-efi/src/protocols/disk_io.rs +4 -4
  54. data/rust-vendor/r-efi/src/protocols/disk_io2.rs +8 -8
  55. data/rust-vendor/r-efi/src/protocols/driver_binding.rs +6 -6
  56. data/rust-vendor/r-efi/src/protocols/driver_diagnostics2.rs +2 -2
  57. data/rust-vendor/r-efi/src/protocols/driver_family_override.rs +2 -2
  58. data/rust-vendor/r-efi/src/protocols/file.rs +28 -28
  59. data/rust-vendor/r-efi/src/protocols/graphics_output.rs +6 -6
  60. data/rust-vendor/r-efi/src/protocols/hii_database.rs +24 -24
  61. data/rust-vendor/r-efi/src/protocols/hii_font.rs +8 -8
  62. data/rust-vendor/r-efi/src/protocols/hii_font_ex.rs +10 -10
  63. data/rust-vendor/r-efi/src/protocols/hii_string.rs +10 -10
  64. data/rust-vendor/r-efi/src/protocols/ip4.rs +16 -16
  65. data/rust-vendor/r-efi/src/protocols/ip6.rs +18 -18
  66. data/rust-vendor/r-efi/src/protocols/load_file.rs +2 -2
  67. data/rust-vendor/r-efi/src/protocols/loaded_image.rs +2 -2
  68. data/rust-vendor/r-efi/src/protocols/managed_network.rs +16 -16
  69. data/rust-vendor/r-efi/src/protocols/memory_attribute.rs +6 -6
  70. data/rust-vendor/r-efi/src/protocols/mp_services.rs +15 -15
  71. data/rust-vendor/r-efi/src/protocols/pci_io.rs +26 -26
  72. data/rust-vendor/r-efi/src/protocols/platform_driver_override.rs +6 -6
  73. data/rust-vendor/r-efi/src/protocols/rng.rs +4 -4
  74. data/rust-vendor/r-efi/src/protocols/service_binding.rs +4 -4
  75. data/rust-vendor/r-efi/src/protocols/shell.rs +81 -81
  76. data/rust-vendor/r-efi/src/protocols/shell_dynamic_command.rs +4 -4
  77. data/rust-vendor/r-efi/src/protocols/simple_file_system.rs +2 -2
  78. data/rust-vendor/r-efi/src/protocols/simple_network.rs +26 -26
  79. data/rust-vendor/r-efi/src/protocols/simple_text_input.rs +4 -4
  80. data/rust-vendor/r-efi/src/protocols/simple_text_input_ex.rs +11 -11
  81. data/rust-vendor/r-efi/src/protocols/simple_text_output.rs +18 -18
  82. data/rust-vendor/r-efi/src/protocols/tcp4.rs +20 -20
  83. data/rust-vendor/r-efi/src/protocols/tcp6.rs +18 -18
  84. data/rust-vendor/r-efi/src/protocols/timestamp.rs +3 -3
  85. data/rust-vendor/r-efi/src/protocols/udp4.rs +16 -16
  86. data/rust-vendor/r-efi/src/protocols/udp6.rs +14 -14
  87. data/rust-vendor/r-efi/src/system.rs +115 -115
  88. data/rust-vendor/r-efi/src/vendor/intel/console_control.rs +6 -6
  89. data/rust-vendor/r-efi-5.3.0/.cargo-checksum.json +1 -0
  90. data/rust-vendor/r-efi-5.3.0/.cargo_vcs_info.json +6 -0
  91. data/rust-vendor/r-efi-5.3.0/.github/workflows/publish.yml +39 -0
  92. data/rust-vendor/r-efi-5.3.0/.github/workflows/rust-tests.yml +125 -0
  93. data/rust-vendor/r-efi-5.3.0/AUTHORS +74 -0
  94. data/rust-vendor/r-efi-5.3.0/Cargo.lock +16 -0
  95. data/rust-vendor/r-efi-5.3.0/Cargo.toml +70 -0
  96. data/rust-vendor/r-efi-5.3.0/Cargo.toml.orig +51 -0
  97. data/rust-vendor/r-efi-5.3.0/Makefile +85 -0
  98. data/rust-vendor/r-efi-5.3.0/NEWS.md +301 -0
  99. data/rust-vendor/r-efi-5.3.0/README.md +99 -0
  100. data/rust-vendor/r-efi-5.3.0/examples/freestanding.rs +34 -0
  101. data/rust-vendor/r-efi-5.3.0/examples/gop-query.rs +188 -0
  102. data/rust-vendor/r-efi-5.3.0/examples/hello-world.rs +55 -0
  103. data/rust-vendor/r-efi-5.3.0/src/base.rs +993 -0
  104. data/rust-vendor/r-efi-5.3.0/src/hii.rs +1300 -0
  105. data/rust-vendor/r-efi-5.3.0/src/lib.rs +182 -0
  106. data/rust-vendor/r-efi-5.3.0/src/protocols/absolute_pointer.rs +69 -0
  107. data/rust-vendor/r-efi-5.3.0/src/protocols/block_io.rs +70 -0
  108. data/rust-vendor/r-efi-5.3.0/src/protocols/bus_specific_driver_override.rs +32 -0
  109. data/rust-vendor/r-efi-5.3.0/src/protocols/debug_support.rs +835 -0
  110. data/rust-vendor/r-efi-5.3.0/src/protocols/debugport.rs +42 -0
  111. data/rust-vendor/r-efi-5.3.0/src/protocols/decompress.rs +37 -0
  112. data/rust-vendor/r-efi-5.3.0/src/protocols/device_path.rs +82 -0
  113. data/rust-vendor/r-efi-5.3.0/src/protocols/device_path_from_text.rs +26 -0
  114. data/rust-vendor/r-efi-5.3.0/src/protocols/device_path_to_text.rs +30 -0
  115. data/rust-vendor/r-efi-5.3.0/src/protocols/device_path_utilities.rs +63 -0
  116. data/rust-vendor/r-efi-5.3.0/src/protocols/disk_io.rs +40 -0
  117. data/rust-vendor/r-efi-5.3.0/src/protocols/disk_io2.rs +58 -0
  118. data/rust-vendor/r-efi-5.3.0/src/protocols/driver_binding.rs +42 -0
  119. data/rust-vendor/r-efi-5.3.0/src/protocols/driver_diagnostics2.rs +38 -0
  120. data/rust-vendor/r-efi-5.3.0/src/protocols/driver_family_override.rs +23 -0
  121. data/rust-vendor/r-efi-5.3.0/src/protocols/file.rs +183 -0
  122. data/rust-vendor/r-efi-5.3.0/src/protocols/graphics_output.rs +103 -0
  123. data/rust-vendor/r-efi-5.3.0/src/protocols/hii_database.rs +299 -0
  124. data/rust-vendor/r-efi-5.3.0/src/protocols/hii_font.rs +87 -0
  125. data/rust-vendor/r-efi-5.3.0/src/protocols/hii_font_ex.rs +107 -0
  126. data/rust-vendor/r-efi-5.3.0/src/protocols/hii_package_list.rs +14 -0
  127. data/rust-vendor/r-efi-5.3.0/src/protocols/hii_string.rs +71 -0
  128. data/rust-vendor/r-efi-5.3.0/src/protocols/ip4.rs +202 -0
  129. data/rust-vendor/r-efi-5.3.0/src/protocols/ip6.rs +264 -0
  130. data/rust-vendor/r-efi-5.3.0/src/protocols/load_file.rs +26 -0
  131. data/rust-vendor/r-efi-5.3.0/src/protocols/load_file2.rs +15 -0
  132. data/rust-vendor/r-efi-5.3.0/src/protocols/loaded_image.rs +39 -0
  133. data/rust-vendor/r-efi-5.3.0/src/protocols/loaded_image_device_path.rs +13 -0
  134. data/rust-vendor/r-efi-5.3.0/src/protocols/managed_network.rs +147 -0
  135. data/rust-vendor/r-efi-5.3.0/src/protocols/memory_attribute.rs +40 -0
  136. data/rust-vendor/r-efi-5.3.0/src/protocols/mp_services.rs +121 -0
  137. data/rust-vendor/r-efi-5.3.0/src/protocols/pci_io.rs +203 -0
  138. data/rust-vendor/r-efi-5.3.0/src/protocols/platform_driver_override.rs +46 -0
  139. data/rust-vendor/r-efi-5.3.0/src/protocols/rng.rs +83 -0
  140. data/rust-vendor/r-efi-5.3.0/src/protocols/service_binding.rs +20 -0
  141. data/rust-vendor/r-efi-5.3.0/src/protocols/shell.rs +295 -0
  142. data/rust-vendor/r-efi-5.3.0/src/protocols/shell_dynamic_command.rs +33 -0
  143. data/rust-vendor/r-efi-5.3.0/src/protocols/shell_parameters.rs +23 -0
  144. data/rust-vendor/r-efi-5.3.0/src/protocols/simple_file_system.rs +26 -0
  145. data/rust-vendor/r-efi-5.3.0/src/protocols/simple_network.rs +196 -0
  146. data/rust-vendor/r-efi-5.3.0/src/protocols/simple_text_input.rs +38 -0
  147. data/rust-vendor/r-efi-5.3.0/src/protocols/simple_text_input_ex.rs +85 -0
  148. data/rust-vendor/r-efi-5.3.0/src/protocols/simple_text_output.rs +86 -0
  149. data/rust-vendor/r-efi-5.3.0/src/protocols/tcp4.rs +224 -0
  150. data/rust-vendor/r-efi-5.3.0/src/protocols/tcp6.rs +202 -0
  151. data/rust-vendor/r-efi-5.3.0/src/protocols/timestamp.rs +32 -0
  152. data/rust-vendor/r-efi-5.3.0/src/protocols/udp4.rs +151 -0
  153. data/rust-vendor/r-efi-5.3.0/src/protocols/udp6.rs +137 -0
  154. data/rust-vendor/r-efi-5.3.0/src/protocols.rs +54 -0
  155. data/rust-vendor/r-efi-5.3.0/src/system.rs +1130 -0
  156. data/rust-vendor/r-efi-5.3.0/src/vendor/intel/console_control.rs +37 -0
  157. data/rust-vendor/r-efi-5.3.0/src/vendor.rs +10 -0
  158. data/rust-vendor/tokio/.cargo-checksum.json +1 -1
  159. data/rust-vendor/tokio/.cargo_vcs_info.json +1 -1
  160. data/rust-vendor/tokio/CHANGELOG.md +94 -0
  161. data/rust-vendor/tokio/Cargo.lock +1549 -0
  162. data/rust-vendor/tokio/Cargo.toml +96 -83
  163. data/rust-vendor/tokio/Cargo.toml.orig +7 -7
  164. data/rust-vendor/tokio/README.md +1 -1
  165. data/rust-vendor/tokio/src/fs/open_options.rs +4 -1
  166. data/rust-vendor/tokio/src/fs/read.rs +4 -1
  167. data/rust-vendor/tokio/src/fs/write.rs +4 -1
  168. data/rust-vendor/tokio/src/io/async_write.rs +3 -4
  169. data/rust-vendor/tokio/src/io/poll_evented.rs +23 -1
  170. data/rust-vendor/tokio/src/io/stderr.rs +15 -1
  171. data/rust-vendor/tokio/src/io/stdout.rs +14 -0
  172. data/rust-vendor/tokio/src/io/util/async_write_ext.rs +2 -2
  173. data/rust-vendor/tokio/src/io/util/write_buf.rs +11 -2
  174. data/rust-vendor/tokio/src/lib.rs +12 -28
  175. data/rust-vendor/tokio/src/macros/select.rs +6 -8
  176. data/rust-vendor/tokio/src/net/tcp/socket.rs +25 -1
  177. data/rust-vendor/tokio/src/net/tcp/stream.rs +40 -1
  178. data/rust-vendor/tokio/src/process/unix/pidfd_reaper.rs +1 -41
  179. data/rust-vendor/tokio/src/runtime/blocking/pool.rs +18 -14
  180. data/rust-vendor/tokio/src/runtime/builder.rs +10 -4
  181. data/rust-vendor/tokio/src/runtime/handle.rs +3 -2
  182. data/rust-vendor/tokio/src/runtime/io/driver/uring.rs +49 -61
  183. data/rust-vendor/tokio/src/runtime/io/driver.rs +6 -5
  184. data/rust-vendor/tokio/src/runtime/mod.rs +20 -1
  185. data/rust-vendor/tokio/src/runtime/runtime.rs +71 -1
  186. data/rust-vendor/tokio/src/runtime/scheduler/current_thread/mod.rs +24 -8
  187. data/rust-vendor/tokio/src/runtime/scheduler/multi_thread/worker.rs +5 -0
  188. data/rust-vendor/tokio/src/runtime/task/core.rs +1 -0
  189. data/rust-vendor/tokio/src/runtime/task/join.rs +7 -3
  190. data/rust-vendor/tokio/src/runtime/task/list.rs +5 -3
  191. data/rust-vendor/tokio/src/runtime/task/mod.rs +0 -5
  192. data/rust-vendor/tokio/src/runtime/tests/loom_blocking.rs +39 -1
  193. data/rust-vendor/tokio/src/signal/mod.rs +6 -17
  194. data/rust-vendor/tokio/src/signal/registry.rs +1 -1
  195. data/rust-vendor/tokio/src/signal/unix.rs +24 -44
  196. data/rust-vendor/tokio/src/signal/windows/sys.rs +52 -64
  197. data/rust-vendor/tokio/src/signal/windows.rs +35 -23
  198. data/rust-vendor/tokio/src/sync/mpsc/mod.rs +3 -1
  199. data/rust-vendor/tokio/src/sync/oneshot.rs +13 -0
  200. data/rust-vendor/tokio/src/sync/rwlock.rs +4 -5
  201. data/rust-vendor/tokio/src/sync/tests/loom_oneshot.rs +27 -1
  202. data/rust-vendor/tokio/src/task/blocking.rs +16 -1
  203. data/rust-vendor/tokio/src/task/builder.rs +2 -2
  204. data/rust-vendor/tokio/src/task/mod.rs +1 -1
  205. data/rust-vendor/tokio/src/task/spawn.rs +8 -3
  206. data/rust-vendor/tokio/src/task/yield_now.rs +13 -23
  207. data/rust-vendor/tokio/src/time/clock.rs +62 -0
  208. data/rust-vendor/tokio/src/util/memchr.rs +32 -4
  209. data/rust-vendor/tokio/src/util/sharded_list.rs +6 -4
  210. data/rust-vendor/tokio/tests/fs_link.rs +54 -0
  211. data/rust-vendor/tokio/tests/io_async_fd_memory_leak.rs +209 -0
  212. data/rust-vendor/tokio/tests/io_write_buf.rs +56 -0
  213. data/rust-vendor/tokio/tests/process_issue_7144.rs +8 -0
  214. data/rust-vendor/tokio/tests/rt_basic.rs +41 -0
  215. data/rust-vendor/tokio/tests/rt_common_before_park.rs +92 -0
  216. data/rust-vendor/tokio/tests/rt_metrics.rs +1 -1
  217. data/rust-vendor/tokio/tests/rt_panic.rs +12 -0
  218. data/rust-vendor/tokio/tests/rt_shutdown_err.rs +82 -0
  219. data/rust-vendor/tokio/tests/rt_threaded.rs +49 -1
  220. data/rust-vendor/tokio/tests/rt_unstable_metrics.rs +32 -0
  221. data/rust-vendor/tokio/tests/tcp_connect.rs +2 -3
  222. data/rust-vendor/tokio/tests/tcp_shutdown.rs +1 -3
  223. data/rust-vendor/tokio/tests/tcp_socket.rs +3 -4
  224. data/rust-vendor/tokio/tests/tcp_stream.rs +3 -0
  225. metadata +78 -3
  226. 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
- // num_idle should now be tracked exactly, panic
578
- // with a descriptive message if it is not the
579
- // case.
580
- let prev_idle = self.metrics.dec_num_idle_threads();
581
- assert!(
582
- prev_idle >= self.metrics.num_idle_threads(),
583
- "num_idle_threads underflowed on thread exit"
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-runtime-worker".into()),
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-runtime-worker".
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-runtime-worker".into()`.
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 frequently yield,
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
- self.uring.replace(IoUring::new(DEFAULT_RING_SIZE)?);
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
- pub(crate) fn check_and_init(&self) -> io::Result<bool> {
186
- match State::from_usize(self.uring_state.load(Ordering::Acquire)) {
187
- State::Uninitialized => match self.try_init() {
188
- Ok(()) => {
189
- self.set_uring_state(State::Initialized);
190
- Ok(true)
191
- }
192
- // If the system doesn't support io_uring, we set the state to Unsupported.
193
- Err(e) if e.raw_os_error() == Some(libc::ENOSYS) => {
194
- self.set_uring_state(State::Unsupported);
195
- Ok(false)
196
- }
197
- // If we get EPERM, io-uring syscalls may be blocked (for example, by seccomp).
198
- // In this case, we try to fall back to spawn_blocking for this and future operations.
199
- // See also: https://github.com/tokio-rs/tokio/issues/7691
200
- Err(e) if e.raw_os_error() == Some(libc::EPERM) => {
201
- self.set_uring_state(State::Unsupported);
202
- Ok(false)
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
- // For other system errors, we just return it.
205
- Err(e) => Err(e),
206
- },
207
- State::Unsupported => Ok(false),
208
- State::Initialized => Ok(true),
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
- // Note: Maybe this check can be removed if upstream callers consistently use `check_and_init`.
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::loom::sync::atomic::AtomicUsize;
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) uring_state: AtomicUsize,
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
- uring_state: AtomicUsize::new(0),
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
- self.registry.deregister(source)?;
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
- Ok(())
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
+ }