Skip to main content

async_io_mini/
lib.rs

1//! Async I/O for the ESP IDF (and possibly other MCU RTOSes supporting the [select] call and BSD Sockets).
2//!
3//! This crate provides [`Async`], an adapter for standard networking types (and [many other] types) to use in
4//! async programs.
5//!
6//! # Implementation
7//!
8//! The first time [`Async`] is used, a thread called "async-io-mini" will be spawned.
9//! The purpose of this thread is to wait for I/O events reported by the OS, and then
10//! wake appropriate futures blocked on I/O when they can be resumed. Its stack is
11//! [`REACTOR_STACK_SIZE`] bytes, selectable with the `stack-size-*` features.
12//!
13//! Note that "async-io-mini" is the Rust-level thread name. On the ESP IDF the name of
14//! the underlying RTOS task is taken from `esp_pthread_cfg_t` rather than from the Rust
15//! thread name, so the reactor shows up as "pthread" in panic reports and task dumps.
16//!
17//! To wait for the next I/O event, the task uses the [select] syscall available on many operating systems.
18//!
19//! # Examples
20//!
21//! Connect to `example.com:80`.
22//!
23//! ```
24//! use async_io_mini::Async;
25//!
26//! use std::net::{TcpStream, ToSocketAddrs};
27//!
28//! # futures_lite::future::block_on(async {
29//! let addr = "example.com:80".to_socket_addrs()?.next().unwrap();
30//!
31//! let stream = Async::<TcpStream>::connect(addr).await?;
32//! # std::io::Result::Ok(()) });
33//! ```
34
35#![allow(unknown_lints)]
36#![allow(clippy::needless_maybe_sized)]
37
38use cfg_if::cfg_if;
39
40pub use io::*;
41#[cfg(feature = "embassy-time")]
42pub use timer::*;
43
44mod io;
45mod reactor;
46mod sys;
47#[cfg(feature = "embassy-time")]
48mod timer;
49
50cfg_if! {
51    if #[cfg(feature = "stack-size-8192")] {
52        /// The size (in bytes) of the stack of the reactor thread.
53        ///
54        /// Select a different size with one of the `stack-size-*` features. Anything
55        /// the reactor calls runs on this stack, including the platform `select`
56        /// implementation and - on MCUs where interrupts are serviced on the stack of
57        /// the interrupted task, as is the case on RISC-V - interrupt handlers.
58        pub const REACTOR_STACK_SIZE: usize = 8192;
59    } else if #[cfg(feature = "stack-size-7168")] {
60        /// The size (in bytes) of the stack of the reactor thread.
61        pub const REACTOR_STACK_SIZE: usize = 7168;
62    } else if #[cfg(feature = "stack-size-6144")] {
63        /// The size (in bytes) of the stack of the reactor thread.
64        pub const REACTOR_STACK_SIZE: usize = 6144;
65    } else if #[cfg(feature = "stack-size-5120")] {
66        /// The size (in bytes) of the stack of the reactor thread.
67        pub const REACTOR_STACK_SIZE: usize = 5120;
68    } else if #[cfg(feature = "stack-size-3072")] {
69        /// The size (in bytes) of the stack of the reactor thread.
70        pub const REACTOR_STACK_SIZE: usize = 3072;
71    } else if #[cfg(feature = "stack-size-2048")] {
72        /// The size (in bytes) of the stack of the reactor thread.
73        pub const REACTOR_STACK_SIZE: usize = 2048;
74    } else { // Default (`stack-size-4096`)
75        /// The size (in bytes) of the stack of the reactor thread.
76        ///
77        /// Select a different size with one of the `stack-size-*` features. Anything
78        /// the reactor calls runs on this stack, including the platform `select`
79        /// implementation and - on MCUs where interrupts are serviced on the stack of
80        /// the interrupted task, as is the case on RISC-V - interrupt handlers.
81        pub const REACTOR_STACK_SIZE: usize = 4096;
82    }
83}