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
@@ -15,7 +15,7 @@ use crate::util::{waker_ref, RngSeedGenerator, Wake, WakerRef};
15
15
  use std::cell::RefCell;
16
16
  use std::collections::VecDeque;
17
17
  use std::future::{poll_fn, Future};
18
- use std::sync::atomic::Ordering::{AcqRel, Release};
18
+ use std::sync::atomic::Ordering::{AcqRel, Acquire, Release};
19
19
  use std::task::Poll::{Pending, Ready};
20
20
  use std::task::Waker;
21
21
  use std::thread::ThreadId;
@@ -380,9 +380,9 @@ impl Context {
380
380
  core = c;
381
381
  }
382
382
 
383
- // This check will fail if `before_park` spawns a task for us to run
384
- // instead of parking the thread
385
- if core.tasks.is_empty() {
383
+ // If `before_park` spawns a task (or otherwise schedules work for us), then we should not
384
+ // park the thread.
385
+ if !self.has_pending_work(&core) {
386
386
  // Park until the thread is signaled
387
387
  core.metrics.about_to_park();
388
388
  core.submit_metrics(handle);
@@ -414,6 +414,10 @@ impl Context {
414
414
  core
415
415
  }
416
416
 
417
+ fn has_pending_work(&self, core: &Core) -> bool {
418
+ !core.tasks.is_empty() || !self.defer.is_empty() || self.handle.shared.woken.load(Acquire)
419
+ }
420
+
417
421
  fn park_internal(
418
422
  &self,
419
423
  core: Box<Core>,
@@ -499,7 +503,7 @@ impl Handle {
499
503
  F: crate::future::Future + 'static,
500
504
  F::Output: 'static,
501
505
  {
502
- // Safety: the caller guarantees that the this is only called on a `LocalRuntime`.
506
+ // Safety: the caller guarantees that this is only called on a `LocalRuntime`.
503
507
  let (handle, notified) = unsafe {
504
508
  me.shared
505
509
  .owned
@@ -720,8 +724,20 @@ impl Wake for Handle {
720
724
 
721
725
  /// Wake by reference
722
726
  fn wake_by_ref(arc_self: &Arc<Self>) {
723
- arc_self.shared.woken.store(true, Release);
724
- arc_self.driver.unpark();
727
+ let already_woken = arc_self.shared.woken.swap(true, Release);
728
+
729
+ if !already_woken {
730
+ use scheduler::Context::CurrentThread;
731
+
732
+ // If we are already running on the runtime, then it's not required to wake up the
733
+ // runtime.
734
+ context::with_scheduler(|maybe_cx| match maybe_cx {
735
+ Some(CurrentThread(cx)) if Arc::ptr_eq(arc_self, &cx.handle) => {}
736
+ _ => {
737
+ arc_self.driver.unpark();
738
+ }
739
+ });
740
+ }
725
741
  }
726
742
  }
727
743
 
@@ -775,7 +791,7 @@ impl CoreGuard<'_> {
775
791
  None => {
776
792
  core.metrics.end_processing_scheduled_tasks();
777
793
 
778
- core = if !context.defer.is_empty() {
794
+ core = if context.has_pending_work(&core) {
779
795
  context.park_yield(core, handle)
780
796
  } else {
781
797
  context.park(core, handle)
@@ -424,6 +424,10 @@ where
424
424
 
425
425
  let cx = maybe_cx.expect("no .is_some() == false cases above should lead here");
426
426
 
427
+ // Since deferred tasks don't stay on `core`, make sure to wake them
428
+ // before blocking.
429
+ cx.defer.wake();
430
+
427
431
  // Get the worker core. If none is set, then blocking is fine!
428
432
  let mut core = match cx.core.borrow_mut().take() {
429
433
  Some(core) => core,
@@ -1280,6 +1284,7 @@ impl Handle {
1280
1284
  });
1281
1285
  }
1282
1286
 
1287
+ // Separated case to reduce LLVM codegen in `Handle::bind_new_task`.
1283
1288
  pub(super) fn schedule_option_task_without_yield(&self, task: Option<Notified>) {
1284
1289
  if let Some(task) = task {
1285
1290
  self.schedule_task(task, false);
@@ -204,6 +204,7 @@ pub(super) struct Trailer {
204
204
  /// Consumer task waiting on completion of this task.
205
205
  pub(super) waker: UnsafeCell<Option<Waker>>,
206
206
  /// Optional hooks needed in the harness.
207
+ #[cfg_attr(not(tokio_unstable), allow(dead_code))] //TODO: remove when hooks are stabilized
207
208
  pub(super) hooks: TaskHarnessScheduleHooks,
208
209
  }
209
210
 
@@ -1,4 +1,4 @@
1
- use crate::runtime::task::{Header, RawTask};
1
+ use crate::runtime::task::{AbortHandle, Header, RawTask};
2
2
 
3
3
  use std::fmt;
4
4
  use std::future::Future;
@@ -22,6 +22,10 @@ cfg_rt! {
22
22
  /// This `struct` is created by the [`task::spawn`] and [`task::spawn_blocking`]
23
23
  /// functions.
24
24
  ///
25
+ /// It is guaranteed that the destructor of the spawned task has finished
26
+ /// before task completion is observed via `JoinHandle` `await`,
27
+ /// [`JoinHandle::is_finished`] or [`AbortHandle::is_finished`].
28
+ ///
25
29
  /// # Cancel safety
26
30
  ///
27
31
  /// The `&mut JoinHandle<T>` type is cancel safe. If it is used as the event
@@ -300,9 +304,9 @@ impl<T> JoinHandle<T> {
300
304
  /// ```
301
305
  /// [cancelled]: method@super::error::JoinError::is_cancelled
302
306
  #[must_use = "abort handles do nothing unless `.abort` is called"]
303
- pub fn abort_handle(&self) -> super::AbortHandle {
307
+ pub fn abort_handle(&self) -> AbortHandle {
304
308
  self.raw.ref_inc();
305
- super::AbortHandle::new(self.raw)
309
+ AbortHandle::new(self.raw)
306
310
  }
307
311
 
308
312
  /// Returns a [task ID] that uniquely identifies this task relative to other
@@ -193,9 +193,11 @@ impl<S: 'static> OwnedTasks<S> {
193
193
  self.list.len()
194
194
  }
195
195
 
196
- cfg_64bit_metrics! {
197
- pub(crate) fn spawned_tasks_count(&self) -> u64 {
198
- self.list.added()
196
+ cfg_unstable_metrics! {
197
+ cfg_64bit_metrics! {
198
+ pub(crate) fn spawned_tasks_count(&self) -> u64 {
199
+ self.list.added()
200
+ }
199
201
  }
200
202
  }
201
203
 
@@ -178,10 +178,6 @@
178
178
  //! poll call will notice it when the poll finishes, and the task is cancelled
179
179
  //! at that point.
180
180
 
181
- // Some task infrastructure is here to support `JoinSet`, which is currently
182
- // unstable. This should be removed once `JoinSet` is stabilized.
183
- #![cfg_attr(not(tokio_unstable), allow(dead_code))]
184
-
185
181
  mod core;
186
182
  use self::core::Cell;
187
183
  use self::core::Header;
@@ -193,7 +189,6 @@ mod harness;
193
189
  use self::harness::Harness;
194
190
 
195
191
  mod id;
196
- #[cfg_attr(not(tokio_unstable), allow(unreachable_pub, unused_imports))]
197
192
  pub use id::{id, try_id, Id};
198
193
 
199
194
  #[cfg(feature = "rt")]
@@ -1,6 +1,7 @@
1
1
  use crate::runtime::{self, Runtime};
2
2
 
3
3
  use std::sync::Arc;
4
+ use std::time::Duration;
4
5
 
5
6
  #[test]
6
7
  fn blocking_shutdown() {
@@ -75,7 +76,6 @@ fn spawn_mandatory_blocking_should_run_even_when_shutting_down_from_other_thread
75
76
 
76
77
  #[test]
77
78
  fn spawn_blocking_when_paused() {
78
- use std::time::Duration;
79
79
  loom::model(|| {
80
80
  let rt = crate::runtime::Builder::new_current_thread()
81
81
  .enable_time()
@@ -94,6 +94,44 @@ fn spawn_blocking_when_paused() {
94
94
  });
95
95
  }
96
96
 
97
+ #[test]
98
+ /// See <https://github.com/tokio-rs/tokio/pull/7922>
99
+ fn spawn_blocking_then_shutdown() {
100
+ loom::model(|| {
101
+ let rt = crate::runtime::Builder::new_current_thread()
102
+ .max_blocking_threads(1)
103
+ .thread_keep_alive(Duration::from_secs(7200)) // don't let the thread exit on its own
104
+ .build()
105
+ .unwrap();
106
+ let rt_hdl = rt.handle().clone();
107
+
108
+ // Currently, there is no live blocking thread,
109
+ // so `spawn_blocking` will spawn a new blocking thread.
110
+ let jh0 = rt_hdl.spawn_blocking(|| {});
111
+ loom::future::block_on(jh0).unwrap();
112
+
113
+ // Now, there is a idle blocking threads park on the condvar,
114
+ // so the following `spawn_blocking` will decrease the `num_idle_threads`
115
+ // and then notify one of the idle threads to run the task.
116
+
117
+ // this will decrease the `num_idle_threads`
118
+ // and then notify one of the idle threads to run the task.
119
+ let jh3 = rt_hdl.spawn_blocking(|| {});
120
+
121
+ // shutdown the runtime, which also shutdown the blocking pool
122
+ drop(rt);
123
+
124
+ // loom will emulate two parrel operations:
125
+ //
126
+ // 1. the blocking thread is woken up on the condvar
127
+ // 2. the main thread is waiting for the blocking thread to finish the task
128
+ //
129
+ // So, if the `num_idle_threads` is not counted correctly,
130
+ // it will trigger the assertions inside the `Inner::run` function.
131
+ let _ = loom::future::block_on(jh3);
132
+ });
133
+ }
134
+
97
135
  fn mk_runtime(num_threads: usize) -> Runtime {
98
136
  runtime::Builder::new_multi_thread()
99
137
  .worker_threads(num_threads)
@@ -50,16 +50,9 @@ mod ctrl_c;
50
50
  #[cfg(feature = "signal")]
51
51
  pub use ctrl_c::ctrl_c;
52
52
 
53
+ #[cfg(unix)]
53
54
  pub(crate) mod registry;
54
55
 
55
- mod os {
56
- #[cfg(unix)]
57
- pub(crate) use super::unix::{OsExtraData, OsStorage};
58
-
59
- #[cfg(windows)]
60
- pub(crate) use super::windows::{OsExtraData, OsStorage};
61
- }
62
-
63
56
  pub mod unix;
64
57
  pub mod windows;
65
58
 
@@ -83,18 +76,14 @@ impl RxFuture {
83
76
  }
84
77
  }
85
78
 
86
- async fn recv(&mut self) -> Option<()> {
79
+ async fn recv(&mut self) {
87
80
  use std::future::poll_fn;
88
81
  poll_fn(|cx| self.poll_recv(cx)).await
89
82
  }
90
83
 
91
- fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
92
- match self.inner.poll(cx) {
93
- Poll::Pending => Poll::Pending,
94
- Poll::Ready(rx) => {
95
- self.inner.set(make_future(rx));
96
- Poll::Ready(Some(()))
97
- }
98
- }
84
+ fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<()> {
85
+ self.inner
86
+ .poll(cx)
87
+ .map(|rx| self.inner.set(make_future(rx)))
99
88
  }
100
89
  }
@@ -1,4 +1,4 @@
1
- use crate::signal::os::{OsExtraData, OsStorage};
1
+ use crate::signal::unix::{OsExtraData, OsStorage};
2
2
  use crate::sync::watch;
3
3
 
4
4
  use std::ops;
@@ -14,8 +14,7 @@ use crate::sync::watch;
14
14
 
15
15
  use mio::net::UnixStream;
16
16
  use std::io::{self, Error, ErrorKind, Write};
17
- use std::sync::atomic::{AtomicBool, Ordering};
18
- use std::sync::Once;
17
+ use std::sync::OnceLock;
19
18
  use std::task::{Context, Poll};
20
19
 
21
20
  #[cfg(not(any(target_os = "linux", target_os = "illumos")))]
@@ -239,20 +238,10 @@ impl From<SignalKind> for std::os::raw::c_int {
239
238
  }
240
239
  }
241
240
 
241
+ #[derive(Default)]
242
242
  pub(crate) struct SignalInfo {
243
243
  event_info: EventInfo,
244
- init: Once,
245
- initialized: AtomicBool,
246
- }
247
-
248
- impl Default for SignalInfo {
249
- fn default() -> SignalInfo {
250
- SignalInfo {
251
- event_info: EventInfo::default(),
252
- init: Once::new(),
253
- initialized: AtomicBool::new(false),
254
- }
255
- }
244
+ init: OnceLock<Result<(), Option<i32>>>,
256
245
  }
257
246
 
258
247
  /// Our global signal handler for all signals registered by this module.
@@ -294,26 +283,20 @@ fn signal_enable(signal: SignalKind, handle: &Handle) -> io::Result<()> {
294
283
  Some(slot) => slot,
295
284
  None => return Err(io::Error::new(io::ErrorKind::Other, "signal too large")),
296
285
  };
297
- let mut registered = Ok(());
298
- siginfo.init.call_once(|| {
299
- registered = unsafe {
300
- signal_hook_registry::register(signal, move || action(globals, signal)).map(|_| ())
301
- };
302
- if registered.is_ok() {
303
- siginfo.initialized.store(true, Ordering::Relaxed);
304
- }
305
- });
306
- registered?;
307
- // If the call_once failed, it won't be retried on the next attempt to register the signal. In
308
- // such case it is not run, registered is still `Ok(())`, initialized is still `false`.
309
- if siginfo.initialized.load(Ordering::Relaxed) {
310
- Ok(())
311
- } else {
312
- Err(Error::new(
313
- ErrorKind::Other,
314
- "Failed to register signal handler",
315
- ))
316
- }
286
+
287
+ siginfo
288
+ .init
289
+ .get_or_init(|| {
290
+ unsafe { signal_hook_registry::register(signal, move || action(globals, signal)) }
291
+ .map(|_| ())
292
+ .map_err(|e| e.raw_os_error())
293
+ })
294
+ .map_err(|e| {
295
+ e.map_or_else(
296
+ || Error::new(ErrorKind::Other, "registering signal handler failed"),
297
+ Error::from_raw_os_error,
298
+ )
299
+ })
317
300
  }
318
301
 
319
302
  /// An listener for receiving a particular type of OS signal.
@@ -438,7 +421,8 @@ pub(crate) fn signal_with_handle(
438
421
  impl Signal {
439
422
  /// Receives the next signal notification event.
440
423
  ///
441
- /// `None` is returned if no more events can be received by this stream.
424
+ /// Although this returns `Option<()>`, it will never actually return `None`.
425
+ /// This was accidentally exposed and would be a breaking change to be removed.
442
426
  ///
443
427
  /// # Cancel safety
444
428
  ///
@@ -466,19 +450,15 @@ impl Signal {
466
450
  /// }
467
451
  /// ```
468
452
  pub async fn recv(&mut self) -> Option<()> {
469
- self.inner.recv().await
453
+ self.inner.recv().await;
454
+ Some(())
470
455
  }
471
456
 
472
457
  /// Polls to receive the next signal notification event, outside of an
473
458
  /// `async` context.
474
459
  ///
475
- /// This method returns:
476
- ///
477
- /// * `Poll::Pending` if no signals are available but the channel is not
478
- /// closed.
479
- /// * `Poll::Ready(Some(()))` if a signal is available.
480
- /// * `Poll::Ready(None)` if the channel has been closed and all signals
481
- /// sent before it was closed have been received.
460
+ /// Although this returns `Option<()>`, it will never actually return `None`.
461
+ /// This was accidentally exposed and would be a breaking change to be removed.
482
462
  ///
483
463
  /// # Examples
484
464
  ///
@@ -504,7 +484,7 @@ impl Signal {
504
484
  /// }
505
485
  /// ```
506
486
  pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
507
- self.inner.poll_recv(cx)
487
+ self.inner.poll_recv(cx).map(Some)
508
488
  }
509
489
  }
510
490
 
@@ -1,35 +1,37 @@
1
1
  use std::io;
2
- use std::sync::Once;
2
+ use std::sync::OnceLock;
3
3
 
4
- use crate::signal::registry::{globals, EventId, EventInfo, Storage};
5
4
  use crate::signal::RxFuture;
5
+ use crate::sync::watch;
6
6
 
7
7
  use windows_sys::core::BOOL;
8
8
  use windows_sys::Win32::System::Console as console;
9
9
 
10
+ type EventInfo = watch::Sender<()>;
11
+
10
12
  pub(super) fn ctrl_break() -> io::Result<RxFuture> {
11
- new(console::CTRL_BREAK_EVENT)
13
+ new(&registry().ctrl_break)
12
14
  }
13
15
 
14
16
  pub(super) fn ctrl_close() -> io::Result<RxFuture> {
15
- new(console::CTRL_CLOSE_EVENT)
17
+ new(&registry().ctrl_close)
16
18
  }
17
19
 
18
20
  pub(super) fn ctrl_c() -> io::Result<RxFuture> {
19
- new(console::CTRL_C_EVENT)
21
+ new(&registry().ctrl_c)
20
22
  }
21
23
 
22
24
  pub(super) fn ctrl_logoff() -> io::Result<RxFuture> {
23
- new(console::CTRL_LOGOFF_EVENT)
25
+ new(&registry().ctrl_logoff)
24
26
  }
25
27
 
26
28
  pub(super) fn ctrl_shutdown() -> io::Result<RxFuture> {
27
- new(console::CTRL_SHUTDOWN_EVENT)
29
+ new(&registry().ctrl_shutdown)
28
30
  }
29
31
 
30
- fn new(signum: u32) -> io::Result<RxFuture> {
32
+ fn new(event_info: &EventInfo) -> io::Result<RxFuture> {
31
33
  global_init()?;
32
- let rx = globals().register_listener(signum as EventId);
34
+ let rx = event_info.subscribe();
33
35
  Ok(RxFuture::new(rx))
34
36
  }
35
37
 
@@ -40,16 +42,14 @@ fn event_requires_infinite_sleep_in_handler(signum: u32) -> bool {
40
42
  //
41
43
  // For more information, see:
42
44
  // https://learn.microsoft.com/en-us/windows/console/handlerroutine#remarks
43
- match signum {
44
- console::CTRL_CLOSE_EVENT => true,
45
- console::CTRL_LOGOFF_EVENT => true,
46
- console::CTRL_SHUTDOWN_EVENT => true,
47
- _ => false,
48
- }
45
+ matches!(
46
+ signum,
47
+ console::CTRL_CLOSE_EVENT | console::CTRL_LOGOFF_EVENT | console::CTRL_SHUTDOWN_EVENT
48
+ )
49
49
  }
50
50
 
51
51
  #[derive(Debug, Default)]
52
- pub(crate) struct OsStorage {
52
+ struct Registry {
53
53
  ctrl_break: EventInfo,
54
54
  ctrl_close: EventInfo,
55
55
  ctrl_c: EventInfo,
@@ -57,74 +57,62 @@ pub(crate) struct OsStorage {
57
57
  ctrl_shutdown: EventInfo,
58
58
  }
59
59
 
60
- impl Storage for OsStorage {
61
- fn event_info(&self, id: EventId) -> Option<&EventInfo> {
62
- match u32::try_from(id) {
63
- Ok(console::CTRL_BREAK_EVENT) => Some(&self.ctrl_break),
64
- Ok(console::CTRL_CLOSE_EVENT) => Some(&self.ctrl_close),
65
- Ok(console::CTRL_C_EVENT) => Some(&self.ctrl_c),
66
- Ok(console::CTRL_LOGOFF_EVENT) => Some(&self.ctrl_logoff),
67
- Ok(console::CTRL_SHUTDOWN_EVENT) => Some(&self.ctrl_shutdown),
60
+ impl Registry {
61
+ fn event_info(&self, signum: u32) -> Option<&EventInfo> {
62
+ match signum {
63
+ console::CTRL_BREAK_EVENT => Some(&self.ctrl_break),
64
+ console::CTRL_CLOSE_EVENT => Some(&self.ctrl_close),
65
+ console::CTRL_C_EVENT => Some(&self.ctrl_c),
66
+ console::CTRL_LOGOFF_EVENT => Some(&self.ctrl_logoff),
67
+ console::CTRL_SHUTDOWN_EVENT => Some(&self.ctrl_shutdown),
68
68
  _ => None,
69
69
  }
70
70
  }
71
-
72
- fn for_each<'a, F>(&'a self, mut f: F)
73
- where
74
- F: FnMut(&'a EventInfo),
75
- {
76
- f(&self.ctrl_break);
77
- f(&self.ctrl_close);
78
- f(&self.ctrl_c);
79
- f(&self.ctrl_logoff);
80
- f(&self.ctrl_shutdown);
81
- }
82
71
  }
83
72
 
84
- #[derive(Debug, Default)]
85
- pub(crate) struct OsExtraData {}
73
+ fn registry() -> &'static Registry {
74
+ static REGISTRY: OnceLock<Registry> = OnceLock::new();
86
75
 
87
- fn global_init() -> io::Result<()> {
88
- static INIT: Once = Once::new();
76
+ REGISTRY.get_or_init(Default::default)
77
+ }
89
78
 
90
- let mut init = None;
79
+ fn global_init() -> io::Result<()> {
80
+ static INIT: OnceLock<Result<(), Option<i32>>> = OnceLock::new();
91
81
 
92
- INIT.call_once(|| unsafe {
93
- let rc = console::SetConsoleCtrlHandler(Some(handler), 1);
94
- let ret = if rc == 0 {
95
- Err(io::Error::last_os_error())
82
+ INIT.get_or_init(|| {
83
+ let rc = unsafe { console::SetConsoleCtrlHandler(Some(handler), 1) };
84
+ if rc == 0 {
85
+ Err(io::Error::last_os_error().raw_os_error())
96
86
  } else {
97
87
  Ok(())
98
- };
99
-
100
- init = Some(ret);
101
- });
102
-
103
- init.unwrap_or_else(|| Ok(()))
88
+ }
89
+ })
90
+ .map_err(|e| {
91
+ e.map_or_else(
92
+ || io::Error::new(io::ErrorKind::Other, "registering signal handler failed"),
93
+ io::Error::from_raw_os_error,
94
+ )
95
+ })
104
96
  }
105
97
 
106
98
  unsafe extern "system" fn handler(ty: u32) -> BOOL {
107
- let globals = globals();
108
- globals.record_event(ty as EventId);
99
+ // Ignore unknown control signal types.
100
+ let Some(event_info) = registry().event_info(ty) else {
101
+ return 0;
102
+ };
109
103
 
110
- // According to https://docs.microsoft.com/en-us/windows/console/handlerroutine
104
+ // According to https://learn.microsoft.com/en-us/windows/console/handlerroutine
111
105
  // the handler routine is always invoked in a new thread, thus we don't
112
106
  // have the same restrictions as in Unix signal handlers, meaning we can
113
107
  // go ahead and perform the broadcast here.
114
- let event_was_handled = globals.broadcast();
115
-
116
- if event_was_handled && event_requires_infinite_sleep_in_handler(ty) {
117
- loop {
108
+ match event_info.send(()) {
109
+ Ok(_) if event_requires_infinite_sleep_in_handler(ty) => loop {
118
110
  std::thread::park();
119
- }
120
- }
121
-
122
- if event_was_handled {
123
- 1
124
- } else {
111
+ },
112
+ Ok(_) => 1,
125
113
  // No one is listening for this notification any more
126
114
  // let the OS fire the next (possibly the default) handler.
127
- 0
115
+ Err(_) => 0,
128
116
  }
129
117
  }
130
118