1 #![cfg(not(loom))]
2
3 //! Asynchronous file and standard stream adaptation.
4 //!
5 //! This module contains utility methods and adapter types for input/output to
6 //! files or standard streams (`Stdin`, `Stdout`, `Stderr`), and
7 //! filesystem manipulation, for use within (and only within) a Tokio runtime.
8 //!
9 //! Tasks run by *worker* threads should not block, as this could delay
10 //! servicing reactor events. Portable filesystem operations are blocking,
11 //! however. This module offers adapters which use a `blocking` annotation
12 //! to inform the runtime that a blocking operation is required. When
13 //! necessary, this allows the runtime to convert the current thread from a
14 //! *worker* to a *backup* thread, where blocking is acceptable.
15 //!
16 //! ## Usage
17 //!
18 //! Where possible, users should prefer the provided asynchronous-specific
19 //! traits such as [`AsyncRead`], or methods returning a `Future` or `Poll`
20 //! type. Adaptions also extend to traits like `std::io::Read` where methods
21 //! return `std::io::Result`. Be warned that these adapted methods may return
22 //! `std::io::ErrorKind::WouldBlock` if a *worker* thread can not be converted
23 //! to a *backup* thread immediately.
24 //!
25 //! **Warning**: These adapters may create a large number of temporary tasks,
26 //! especially when reading large files. When performing a lot of operations
27 //! in one batch, it may be significantly faster to use [`spawn_blocking`]
28 //! directly:
29 //!
30 //! ```
31 //! use tokio::fs::File;
32 //! use std::io::{BufReader, BufRead};
33 //! async fn count_lines(file: File) -> Result<usize, std::io::Error> {
34 //! let file = file.into_std().await;
35 //! tokio::task::spawn_blocking(move || {
36 //! let line_count = BufReader::new(file).lines().count();
37 //! Ok(line_count)
38 //! }).await?
39 //! }
40 //! ```
41 //!
42 //! [`spawn_blocking`]: fn@crate::task::spawn_blocking
43 //! [`AsyncRead`]: trait@crate::io::AsyncRead
44
45 mod canonicalize;
46 pub use self::canonicalize::canonicalize;
47
48 mod create_dir;
49 pub use self::create_dir::create_dir;
50
51 mod create_dir_all;
52 pub use self::create_dir_all::create_dir_all;
53
54 mod dir_builder;
55 pub use self::dir_builder::DirBuilder;
56
57 mod file;
58 pub use self::file::File;
59
60 mod hard_link;
61 pub use self::hard_link::hard_link;
62
63 mod metadata;
64 pub use self::metadata::metadata;
65
66 mod open_options;
67 pub use self::open_options::OpenOptions;
68
69 mod read;
70 pub use self::read::read;
71
72 mod read_dir;
73 pub use self::read_dir::{read_dir, DirEntry, ReadDir};
74
75 mod read_link;
76 pub use self::read_link::read_link;
77
78 mod read_to_string;
79 pub use self::read_to_string::read_to_string;
80
81 mod remove_dir;
82 pub use self::remove_dir::remove_dir;
83
84 mod remove_dir_all;
85 pub use self::remove_dir_all::remove_dir_all;
86
87 mod remove_file;
88 pub use self::remove_file::remove_file;
89
90 mod rename;
91 pub use self::rename::rename;
92
93 mod set_permissions;
94 pub use self::set_permissions::set_permissions;
95
96 mod symlink_metadata;
97 pub use self::symlink_metadata::symlink_metadata;
98
99 mod write;
100 pub use self::write::write;
101
102 mod copy;
103 pub use self::copy::copy;
104
105 #[cfg(test)]
106 mod mocks;
107
108 feature! {
109 #![unix]
110
111 mod symlink;
112 pub use self::symlink::symlink;
113 }
114
115 feature! {
116 #![windows]
117
118 mod symlink_dir;
119 pub use self::symlink_dir::symlink_dir;
120
121 mod symlink_file;
122 pub use self::symlink_file::symlink_file;
123 }
124
125 use std::io;
126
127 #[cfg(not(test))]
128 use crate::blocking::spawn_blocking;
129 #[cfg(test)]
130 use mocks::spawn_blocking;
131
asyncify<F, T>(f: F) -> io::Result<T> where F: FnOnce() -> io::Result<T> + Send + 'static, T: Send + 'static,132 pub(crate) async fn asyncify<F, T>(f: F) -> io::Result<T>
133 where
134 F: FnOnce() -> io::Result<T> + Send + 'static,
135 T: Send + 'static,
136 {
137 match spawn_blocking(f).await {
138 Ok(res) => res,
139 Err(_) => Err(io::Error::new(
140 io::ErrorKind::Other,
141 "background task failed",
142 )),
143 }
144 }
145