• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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