1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! I/O primitives: TCP listener/stream, UDP socket, native and `tokio`-backed.
//!
//! The native backend is lock-free (`io_uring` on Linux, IOCP on Windows,
//! kqueue via mio on macOS/BSD) plus a thin tokio-backed alternative.
//! Split out of what used to be a single monolithic `lib.rs` — module
//! boundaries mirror the original `native_impl` / `windows_impl` /
//! `tokio_impl` blocks.
use Future;
use Pin;
use ;
pub
pub use *;
pub use *;
pub use ;
// NOTE: named `tokio_backend`, not `tokio` - a local module named `tokio`
// shadows the extern crate `tokio` for path resolution within this file,
// which breaks every `tokio::...` path below. This bit us once already
// (see dtact-util/src/fs/mod.rs's identical note).
pub use *;
/// Resolve `host` (a `"host:port"` string, exactly what
/// `std::net::ToSocketAddrs` accepts) to one or more `SocketAddr`s,
/// without blocking the calling task's thread on the DNS round-trip.
///
/// Unlike every other `native`-backend primitive in this crate, this
/// doesn't need `io_uring`/IOCP/mio at all — `getaddrinfo(3)` (what
/// `std::net::ToSocketAddrs` calls under the hood) has no async variant
/// on any of our target platforms, so the only way to make it not block
/// the caller is to run it on a throwaway thread and hand the result back
/// through a [`crate::sync::oneshot`] channel. One thread per call rather
/// than a persistent pool: DNS lookups are neither hot-path nor
/// typically concurrent enough to justify the extra bookkeeping a pool
/// (like `fs`'s or `process`'s) needs, and callers who *do* look up
/// hosts at high volume should be caching the results anyway, not
/// re-resolving on every connection.
///
/// # Errors
/// Returns whatever `std::net::ToSocketAddrs::to_socket_addrs` returns
/// for `host` (e.g. `host:port` doesn't parse, or the name doesn't
/// resolve), or an I/O error if the resolver thread itself panicked.
///
/// # Panics
/// Panics if the OS refuses to spawn the resolver thread (fatal resource
/// exhaustion) — the same class of failure every other native backend in
/// this crate treats as unrecoverable at thread-spawn time.
pub async
// =========================================================================
// SHARED STREAM TRAITS + COMBINATORS (`BufReader`/`BufWriter`/`copy`)
// =========================================================================
//
// `tokio::io` has a much larger combinator zoo (`Chain`/`Take`/`Lines`/
// `split`/`empty`/`repeat`/`sink`/`stdin`/`stdout`/`stderr`/...) than what
// follows here — this covers the handful actually worth having given
// this crate's own shape, not a 1:1 port:
//
// - No `split()`/`OwnedReadHalf`/`OwnedWriteHalf`. Every stream type this
// trait is implemented for already takes `&self` (not `&mut self`) for
// both `read` and `write` — the reason `tokio::net::TcpStream` needs a
// split at all is that `std`'s I/O traits require `&mut self`, forcing
// one owner. Here, just wrap the stream in an `Arc` and call
// `.read()`/`.write()` from as many tasks as you like; there's nothing
// a split would add.
// - No `Chain`/`Take`/`Lines`/`empty`/`repeat`/`sink`/`stdin`/`stdout`/
// `stderr`: genuinely useful but secondary — add them if/when a real
// use case shows up rather than speculatively.
pub use ;