1
1
use crate :: { SpirvBuilder , SpirvBuilderError , leaf_deps} ;
2
2
use notify:: { Event , RecommendedWatcher , RecursiveMode , Watcher } ;
3
3
use rustc_codegen_spirv_types:: CompileResult ;
4
+ use std:: sync:: mpsc:: TrySendError ;
4
5
use std:: {
5
6
collections:: HashSet ,
6
7
path:: PathBuf ,
@@ -40,19 +41,21 @@ impl SpirvWatcher {
40
41
return Err ( SpirvWatcherError :: WatchWithPrintMetadata . into ( ) ) ;
41
42
}
42
43
43
- let ( tx, rx) = sync_channel ( 0 ) ;
44
+ let ( tx, rx) = sync_channel ( 1 ) ;
44
45
let watcher =
45
46
notify:: recommended_watcher ( move |result : notify:: Result < Event > | match result {
46
47
Ok ( event) => match event. kind {
47
48
notify:: EventKind :: Any
48
49
| notify:: EventKind :: Create ( _)
49
50
| notify:: EventKind :: Modify ( _)
50
51
| notify:: EventKind :: Remove ( _)
51
- | notify:: EventKind :: Other => {
52
- if let Err ( err) = tx. try_send ( ( ) ) {
53
- log:: error!( "send error: {err:?}" ) ;
54
- }
55
- }
52
+ | notify:: EventKind :: Other => match tx. try_send ( ( ) ) {
53
+ Ok ( _) => ( ) ,
54
+ // disconnect is fine, SpirvWatcher is currently dropping
55
+ Err ( TrySendError :: Disconnected ( _) ) => ( ) ,
56
+ // full is fine, we just need to send a single event anyway
57
+ Err ( TrySendError :: Full ( _) ) => ( ) ,
58
+ } ,
56
59
notify:: EventKind :: Access ( _) => { }
57
60
} ,
58
61
Err ( err) => log:: error!( "notify error: {err:?}" ) ,
@@ -78,7 +81,7 @@ impl SpirvWatcher {
78
81
return self . recv_first_result ( ) ;
79
82
}
80
83
81
- self . rx . recv ( ) . expect ( "watcher should be alive" ) ;
84
+ self . rx . recv ( ) . map_err ( |_| SpirvWatcherError :: WatcherDied ) ? ;
82
85
let metadata_file = crate :: invoke_rustc ( & self . builder ) ?;
83
86
let result = self . builder . parse_metadata_file ( & metadata_file) ?;
84
87
@@ -97,7 +100,7 @@ impl SpirvWatcher {
97
100
. watch ( watch_path, RecursiveMode :: Recursive )
98
101
. map_err ( SpirvWatcherError :: NotifyFailed ) ?;
99
102
let path = loop {
100
- self . rx . recv ( ) . expect ( "watcher should be alive" ) ;
103
+ self . rx . recv ( ) . map_err ( |_| SpirvWatcherError :: WatcherDied ) ? ;
101
104
match crate :: invoke_rustc ( & self . builder ) {
102
105
Ok ( path) => break path,
103
106
Err ( err) => log:: error!( "{err}" ) ,
@@ -136,4 +139,6 @@ pub enum SpirvWatcherError {
136
139
WatchWithPrintMetadata ,
137
140
#[ error( "could not notify for changes: {0}" ) ]
138
141
NotifyFailed ( #[ from] notify:: Error ) ,
142
+ #[ error( "watcher died and closed channel" ) ]
143
+ WatcherDied ,
139
144
}
0 commit comments