9
9
//! needs to read-after-write from a file, then it would be added to this
10
10
//! abstraction.
11
11
12
+ use std:: cmp:: max;
12
13
use std:: fs;
13
14
use std:: io;
14
15
use std:: path:: { Path , PathBuf } ;
15
16
use std:: string:: ToString ;
16
17
use std:: sync:: mpsc:: Sender ;
18
+ use std:: thread:: available_parallelism;
19
+ use threadpool:: ThreadPool ;
17
20
18
21
pub ( crate ) trait PathError {
19
22
fn new < S , P : AsRef < Path > > ( e : S , path : P ) -> Self
@@ -24,11 +27,21 @@ pub(crate) trait PathError {
24
27
pub ( crate ) struct DocFS {
25
28
sync_only : bool ,
26
29
errors : Option < Sender < String > > ,
30
+ pool : ThreadPool ,
27
31
}
28
32
29
33
impl DocFS {
30
34
pub ( crate ) fn new ( errors : Sender < String > ) -> DocFS {
31
- DocFS { sync_only : false , errors : Some ( errors) }
35
+ const MINIMUM_NB_THREADS : usize = 2 ;
36
+ DocFS {
37
+ sync_only : false ,
38
+ errors : Some ( errors) ,
39
+ pool : ThreadPool :: new (
40
+ available_parallelism ( )
41
+ . map ( |nb| max ( nb. get ( ) , MINIMUM_NB_THREADS ) )
42
+ . unwrap_or ( MINIMUM_NB_THREADS ) ,
43
+ ) ,
44
+ }
32
45
}
33
46
34
47
pub ( crate ) fn set_sync_only ( & mut self , sync_only : bool ) {
@@ -54,12 +67,11 @@ impl DocFS {
54
67
where
55
68
E : PathError ,
56
69
{
57
- #[ cfg( windows) ]
58
70
if !self . sync_only {
59
71
// A possible future enhancement after more detailed profiling would
60
72
// be to create the file sync so errors are reported eagerly.
61
73
let sender = self . errors . clone ( ) . expect ( "can't write after closing" ) ;
62
- rayon :: spawn ( move || {
74
+ self . pool . execute ( move || {
63
75
fs:: write ( & path, contents) . unwrap_or_else ( |e| {
64
76
sender. send ( format ! ( "\" {}\" : {}" , path. display( ) , e) ) . unwrap_or_else ( |_| {
65
77
panic ! ( "failed to send error on \" {}\" " , path. display( ) )
@@ -70,9 +82,12 @@ impl DocFS {
70
82
fs:: write ( & path, contents) . map_err ( |e| E :: new ( e, path) ) ?;
71
83
}
72
84
73
- #[ cfg( not( windows) ) ]
74
- fs:: write ( & path, contents) . map_err ( |e| E :: new ( e, path) ) ?;
75
-
76
85
Ok ( ( ) )
77
86
}
78
87
}
88
+
89
+ impl Drop for DocFS {
90
+ fn drop ( & mut self ) {
91
+ self . pool . join ( ) ;
92
+ }
93
+ }
0 commit comments