@@ -15,7 +15,7 @@ use notify::event::ModifyKind;
1515use notify:: { Config , Error , Event , EventKind , RecommendedWatcher , RecursiveMode , Watcher } ;
1616use std:: path:: { Path , PathBuf } ;
1717use std:: sync:: Arc ;
18- use std:: sync:: Mutex ;
18+ use std:: sync:: atomic :: { AtomicBool , Ordering } ;
1919use std:: time:: { Duration , Instant } ;
2020
2121#[ derive( Debug , Clone , PartialEq , Eq , Copy ) ]
@@ -230,11 +230,24 @@ fn print_build_failed_footer() {
230230 println ! ( "\n Build failed. Watching for changes..." ) ;
231231}
232232
233+ fn cleanup_before_watch_exit (
234+ path : & Path ,
235+ build_state : & BuildCommandState ,
236+ show_progress : bool ,
237+ message : & str ,
238+ ) {
239+ if show_progress {
240+ println ! ( "{message}" ) ;
241+ }
242+ build:: with_build_lock ( path, || clean:: cleanup_after_build ( build_state) ) ;
243+ }
244+
233245struct AsyncWatchArgs < ' a > {
234246 watcher : & ' a mut RecommendedWatcher ,
235247 current_watch_paths : Vec < ( PathBuf , RecursiveMode ) > ,
236248 initial_build_state : BuildCommandState ,
237249 q : Arc < FifoQueue < Result < Event , Error > > > ,
250+ ctrlc_pressed : Arc < AtomicBool > ,
238251 path : & ' a Path ,
239252 show_progress : bool ,
240253 filter : & ' a Option < regex:: Regex > ,
@@ -252,6 +265,7 @@ async fn async_watch(
252265 mut current_watch_paths,
253266 initial_build_state,
254267 q,
268+ ctrlc_pressed,
255269 path,
256270 show_progress,
257271 filter,
@@ -265,23 +279,9 @@ async fn async_watch(
265279) -> Result < ( ) > {
266280 let mut build_state = initial_build_state;
267281 let mut needs_compile_type = CompileType :: None ;
268- // create a mutex to capture if ctrl-c was pressed
269- let ctrlc_pressed = Arc :: new ( Mutex :: new ( false ) ) ;
270- let ctrlc_pressed_clone = Arc :: clone ( & ctrlc_pressed) ;
271-
272- ctrlc:: set_handler ( move || {
273- let pressed = Arc :: clone ( & ctrlc_pressed) ;
274- let mut pressed = pressed. lock ( ) . unwrap ( ) ;
275- * pressed = true ;
276- } )
277- . expect ( "Error setting Ctrl-C handler" ) ;
278-
279282 loop {
280- if * ctrlc_pressed_clone. lock ( ) . unwrap ( ) {
281- if show_progress {
282- println ! ( "\n Exiting..." ) ;
283- }
284- build:: with_build_lock ( path, || clean:: cleanup_after_build ( & build_state) ) ;
283+ if ctrlc_pressed. load ( Ordering :: SeqCst ) {
284+ cleanup_before_watch_exit ( path, & build_state, show_progress, "\n Exiting..." ) ;
285285 break Ok ( ( ) ) ;
286286 }
287287 let mut events: Vec < Event > = vec ! [ ] ;
@@ -303,10 +303,12 @@ async fn async_watch(
303303 . any ( |path| path. ends_with ( LockKind :: Watch . file_name ( ) ) )
304304 && let EventKind :: Remove ( _) = event. kind
305305 {
306- if show_progress {
307- println ! ( "\n Exiting... (lockfile removed)" ) ;
308- }
309- build:: with_build_lock ( path, || clean:: cleanup_after_build ( & build_state) ) ;
306+ cleanup_before_watch_exit (
307+ path,
308+ & build_state,
309+ show_progress,
310+ "\n Exiting... (lockfile removed)" ,
311+ ) ;
310312 return Ok ( ( ) ) ;
311313 }
312314
@@ -572,6 +574,13 @@ pub fn start(
572574
573575 let path = Path :: new ( folder) ;
574576
577+ let ctrlc_pressed = Arc :: new ( AtomicBool :: new ( false ) ) ;
578+ let ctrlc_pressed_for_handler = Arc :: clone ( & ctrlc_pressed) ;
579+ ctrlc:: set_handler ( move || {
580+ ctrlc_pressed_for_handler. store ( true , Ordering :: SeqCst ) ;
581+ } )
582+ . expect ( "Error setting Ctrl-C handler" ) ;
583+
575584 // Initialization can clean previous build artifacts, so it has to be serialized
576585 // with the initial compile too.
577586 let ( build_state, current_watch_paths, initial_compile_result) : StartupBuildResult =
@@ -612,6 +621,11 @@ pub fn start(
612621 ) )
613622 } ) ?;
614623
624+ if ctrlc_pressed. load ( Ordering :: SeqCst ) {
625+ cleanup_before_watch_exit ( path, & build_state, show_progress, "\n Exiting..." ) ;
626+ return Ok ( ( ) ) ;
627+ }
628+
615629 // Run after-build outside build.lock. Hooks may invoke ReScript commands that need the same lock.
616630 if let Some ( ( timing_total, result) ) = initial_compile_result {
617631 finish_successful_watch_compile (
@@ -630,6 +644,7 @@ pub fn start(
630644 current_watch_paths,
631645 initial_build_state : build_state,
632646 q : consumer,
647+ ctrlc_pressed,
633648 path,
634649 show_progress,
635650 filter,
0 commit comments