|
25 | 25 | //! [`block_on()`] function. The "async-io" thread is therefore just a fallback mechanism |
26 | 26 | //! processing I/O events in case no other threads are. |
27 | 27 | //! |
| 28 | +//! This thread is only spawned under either of the following conditions: |
| 29 | +//! |
| 30 | +//! - [`Async`]s or [`Timer`]s are created without an active [`block_on`] call. |
| 31 | +//! - More than one thread is calling [`block_on`] at a time. |
| 32 | +//! |
| 33 | +//! Therefore, if you would like to prevent this thread from being spawned, ensure |
| 34 | +//! that there is only one thread calling [`block_on`] at a time. This thread |
| 35 | +//! will handle all I/O events in lieu of the "async-io" thread. |
| 36 | +//! |
| 37 | +//! **Note:** If you are using [`async-process`], keep in mind that [`async-process`]'s |
| 38 | +//! reaper thread calls [`block_on`] on Unix platforms in order to reap child |
| 39 | +//! processes. If you are using [`async-process`] and are trying to avoid spawning |
| 40 | +//! the "async-io" thread, ensure that your executor is running the [`async_process::driver()`] |
| 41 | +//! future. In addition, the executor backing [`smol::spawn()`] as well as the |
| 42 | +//! multithreaded version of [`smol_macros::main!`] use [`block_on`] as well. |
| 43 | +//! |
28 | 44 | //! [epoll]: https://en.wikipedia.org/wiki/Epoll |
29 | 45 | //! [kqueue]: https://en.wikipedia.org/wiki/Kqueue |
30 | 46 | //! [event ports]: https://illumos.org/man/port_create |
31 | 47 | //! [IOCP]: https://learn.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports |
32 | 48 | //! [`polling`]: https://docs.rs/polling |
| 49 | +//! [`async-process`]: https://docs.rs/async-process |
| 50 | +//! [`async_process::driver()`]: https://docs.rs/async-process/latest/async_process/fn.driver.html |
| 51 | +//! [`smol::spawn()`]: https://docs.rs/smol/latest/smol/fn.spawn.html |
| 52 | +//! [`smol_macros::main!`]: https://docs.rs/smol-macros/latest/smol_macros/macro.main.html |
33 | 53 | //! |
34 | 54 | //! # Examples |
35 | 55 | //! |
@@ -79,6 +99,10 @@ use std::{ |
79 | 99 | #[cfg(windows)] |
80 | 100 | use std::os::windows::io::{AsRawSocket, AsSocket, BorrowedSocket, OwnedSocket, RawSocket}; |
81 | 101 |
|
| 102 | +// Not public API. |
| 103 | +#[doc(hidden)] |
| 104 | +pub use driver::is_async_io_thread_spawned; |
| 105 | + |
82 | 106 | use futures_io::{AsyncRead, AsyncWrite}; |
83 | 107 | use futures_lite::stream::{self, Stream}; |
84 | 108 |
|
@@ -192,6 +216,8 @@ impl Timer { |
192 | 216 | /// # }); |
193 | 217 | /// ``` |
194 | 218 | pub fn never() -> Timer { |
| 219 | + crate::driver::increment_alive(); |
| 220 | + |
195 | 221 | Timer { |
196 | 222 | id_and_waker: None, |
197 | 223 | when: None, |
@@ -271,6 +297,8 @@ impl Timer { |
271 | 297 | /// # }); |
272 | 298 | /// ``` |
273 | 299 | pub fn interval_at(start: Instant, period: Duration) -> Timer { |
| 300 | + crate::driver::increment_alive(); |
| 301 | + |
274 | 302 | Timer { |
275 | 303 | id_and_waker: None, |
276 | 304 | when: Some(start), |
@@ -458,6 +486,8 @@ impl Drop for Timer { |
458 | 486 | // Deregister the timer from the reactor. |
459 | 487 | Reactor::get().remove_timer(when, id); |
460 | 488 | } |
| 489 | + |
| 490 | + crate::driver::decrement_alive(); |
461 | 491 | } |
462 | 492 | } |
463 | 493 |
|
@@ -680,6 +710,8 @@ impl<T: AsFd> Async<T> { |
680 | 710 | /// it is not set. If not set to non-blocking mode, I/O operations may block the current thread |
681 | 711 | /// and cause a deadlock in an asynchronous context. |
682 | 712 | pub fn new_nonblocking(io: T) -> io::Result<Async<T>> { |
| 713 | + crate::driver::increment_alive(); |
| 714 | + |
683 | 715 | // SAFETY: It is impossible to drop the I/O source while it is registered through |
684 | 716 | // this type. |
685 | 717 | let registration = unsafe { Registration::new(io.as_fd()) }; |
@@ -774,6 +806,8 @@ impl<T: AsSocket> Async<T> { |
774 | 806 | /// it is not set. If not set to non-blocking mode, I/O operations may block the current thread |
775 | 807 | /// and cause a deadlock in an asynchronous context. |
776 | 808 | pub fn new_nonblocking(io: T) -> io::Result<Async<T>> { |
| 809 | + crate::driver::increment_alive(); |
| 810 | + |
777 | 811 | // Create the registration. |
778 | 812 | // |
779 | 813 | // SAFETY: It is impossible to drop the I/O source while it is registered through |
@@ -1165,6 +1199,8 @@ impl<T> Drop for Async<T> { |
1165 | 1199 | // Drop the I/O handle to close it. |
1166 | 1200 | self.io.take(); |
1167 | 1201 | } |
| 1202 | + |
| 1203 | + crate::driver::decrement_alive(); |
1168 | 1204 | } |
1169 | 1205 | } |
1170 | 1206 |
|
|
0 commit comments