Skip to content

Commit 6cf2f47

Browse files
authored
Rollup merge of #109139 - GuillaumeGomez:rustdoc-windows-wait-for-write, r=notriddle
rustdoc: DocFS: Replace rayon with threadpool and enable it for all targets Fixes #109060. Switching to `threadpool` makes it a bit simpler for us to wait for all tasks in `DocFS` directly in the `Drop` implementation. I'm also curious if making all the writes into a thread pool could improve run time for rustdoc on all other platforms than Windows as well. I'll run a perf check to see. cc ```@ehuss``` r? ```@notriddle```
2 parents 1385a32 + e667872 commit 6cf2f47

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

Cargo.lock

+10-1
Original file line numberDiff line numberDiff line change
@@ -5458,13 +5458,13 @@ dependencies = [
54585458
"itertools",
54595459
"minifier",
54605460
"once_cell",
5461-
"rayon",
54625461
"regex",
54635462
"rustdoc-json-types",
54645463
"serde",
54655464
"serde_json",
54665465
"smallvec",
54675466
"tempfile",
5467+
"threadpool",
54685468
"tracing",
54695469
"tracing-subscriber",
54705470
"tracing-tree",
@@ -6209,6 +6209,15 @@ dependencies = [
62096209
"once_cell",
62106210
]
62116211

6212+
[[package]]
6213+
name = "threadpool"
6214+
version = "1.8.1"
6215+
source = "registry+https://github.com/rust-lang/crates.io-index"
6216+
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
6217+
dependencies = [
6218+
"num_cpus",
6219+
]
6220+
62126221
[[package]]
62136222
name = "tidy"
62146223
version = "0.1.0"

src/librustdoc/Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,13 @@ smallvec = "1.8.1"
2020
tempfile = "3"
2121
tracing = "0.1"
2222
tracing-tree = "0.2.0"
23+
threadpool = "1.8.1"
2324

2425
[dependencies.tracing-subscriber]
2526
version = "0.3.3"
2627
default-features = false
2728
features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
2829

29-
[target.'cfg(windows)'.dependencies]
30-
rayon = "1.5.1"
31-
3230
[dev-dependencies]
3331
expect-test = "1.4.0"
3432

src/librustdoc/docfs.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22
//!
33
//! On Windows this indirects IO into threads to work around performance issues
44
//! with Defender (and other similar virus scanners that do blocking operations).
5-
//! On other platforms this is a thin shim to fs.
65
//!
76
//! Only calls needed to permit this workaround have been abstracted: thus
87
//! fs::read is still done directly via the fs module; if in future rustdoc
98
//! needs to read-after-write from a file, then it would be added to this
109
//! abstraction.
1110
11+
use std::cmp::max;
1212
use std::fs;
1313
use std::io;
1414
use std::path::{Path, PathBuf};
1515
use std::string::ToString;
1616
use std::sync::mpsc::Sender;
17+
use std::thread::available_parallelism;
18+
use threadpool::ThreadPool;
1719

1820
pub(crate) trait PathError {
1921
fn new<S, P: AsRef<Path>>(e: S, path: P) -> Self
@@ -24,11 +26,21 @@ pub(crate) trait PathError {
2426
pub(crate) struct DocFS {
2527
sync_only: bool,
2628
errors: Option<Sender<String>>,
29+
pool: ThreadPool,
2730
}
2831

2932
impl DocFS {
3033
pub(crate) fn new(errors: Sender<String>) -> DocFS {
31-
DocFS { sync_only: false, errors: Some(errors) }
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+
}
3244
}
3345

3446
pub(crate) fn set_sync_only(&mut self, sync_only: bool) {
@@ -54,12 +66,11 @@ impl DocFS {
5466
where
5567
E: PathError,
5668
{
57-
#[cfg(windows)]
5869
if !self.sync_only {
5970
// A possible future enhancement after more detailed profiling would
6071
// be to create the file sync so errors are reported eagerly.
6172
let sender = self.errors.clone().expect("can't write after closing");
62-
rayon::spawn(move || {
73+
self.pool.execute(move || {
6374
fs::write(&path, contents).unwrap_or_else(|e| {
6475
sender.send(format!("\"{}\": {}", path.display(), e)).unwrap_or_else(|_| {
6576
panic!("failed to send error on \"{}\"", path.display())
@@ -70,9 +81,12 @@ impl DocFS {
7081
fs::write(&path, contents).map_err(|e| E::new(e, path))?;
7182
}
7283

73-
#[cfg(not(windows))]
74-
fs::write(&path, contents).map_err(|e| E::new(e, path))?;
75-
7684
Ok(())
7785
}
7886
}
87+
88+
impl Drop for DocFS {
89+
fn drop(&mut self) {
90+
self.pool.join();
91+
}
92+
}

0 commit comments

Comments
 (0)