"Fossies" - the Fresh Open Source Software Archive 
Member "rustc-1.72.1-src/src/librustdoc/docfs.rs" (13 Sep 2023, 2788 Bytes) of package /linux/misc/rustc-1.72.1-src.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Rust source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the last
Fossies "Diffs" side-by-side code changes report for "docfs.rs":
1.69.0_vs_1.70.0.
1 //! Rustdoc's FileSystem abstraction module.
2 //!
3 //! On Windows this indirects IO into threads to work around performance issues
4 //! with Defender (and other similar virus scanners that do blocking operations).
5 //!
6 //! Only calls needed to permit this workaround have been abstracted: thus
7 //! fs::read is still done directly via the fs module; if in future rustdoc
8 //! needs to read-after-write from a file, then it would be added to this
9 //! abstraction.
10
11 use std::cmp::max;
12 use std::fs;
13 use std::io;
14 use std::path::{Path, PathBuf};
15 use std::string::ToString;
16 use std::sync::mpsc::Sender;
17 use std::thread::available_parallelism;
18 use threadpool::ThreadPool;
19
20 pub(crate) trait PathError {
21 fn new<S, P: AsRef<Path>>(e: S, path: P) -> Self
22 where
23 S: ToString + Sized;
24 }
25
26 pub(crate) struct DocFS {
27 sync_only: bool,
28 errors: Option<Sender<String>>,
29 pool: ThreadPool,
30 }
31
32 impl DocFS {
33 pub(crate) fn new(errors: Sender<String>) -> DocFS {
34 const MINIMUM_NB_THREADS: usize = 2;
35 DocFS {
36 sync_only: false,
37 errors: Some(errors),
38 pool: ThreadPool::new(
39 available_parallelism()
40 .map(|nb| max(nb.get(), MINIMUM_NB_THREADS))
41 .unwrap_or(MINIMUM_NB_THREADS),
42 ),
43 }
44 }
45
46 pub(crate) fn set_sync_only(&mut self, sync_only: bool) {
47 self.sync_only = sync_only;
48 }
49
50 pub(crate) fn close(&mut self) {
51 self.errors = None;
52 }
53
54 pub(crate) fn create_dir_all<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
55 // For now, dir creation isn't a huge time consideration, do it
56 // synchronously, which avoids needing ordering between write() actions
57 // and directory creation.
58 fs::create_dir_all(path)
59 }
60
61 pub(crate) fn write<E>(
62 &self,
63 path: PathBuf,
64 contents: impl 'static + Send + AsRef<[u8]>,
65 ) -> Result<(), E>
66 where
67 E: PathError,
68 {
69 if !self.sync_only {
70 // A possible future enhancement after more detailed profiling would
71 // be to create the file sync so errors are reported eagerly.
72 let sender = self.errors.clone().expect("can't write after closing");
73 self.pool.execute(move || {
74 fs::write(&path, contents).unwrap_or_else(|e| {
75 sender.send(format!("\"{}\": {}", path.display(), e)).unwrap_or_else(|_| {
76 panic!("failed to send error on \"{}\"", path.display())
77 })
78 });
79 });
80 } else {
81 fs::write(&path, contents).map_err(|e| E::new(e, path))?;
82 }
83
84 Ok(())
85 }
86 }
87
88 impl Drop for DocFS {
89 fn drop(&mut self) {
90 self.pool.join();
91 }
92 }