@@ -382,7 +382,7 @@ async fn read_mdfind_results(
382382 home_dir : & str ,
383383 receiver : & mut tokio:: sync:: watch:: Receiver < ( String , Vec < String > ) > ,
384384 output : & mut iced:: futures:: channel:: mpsc:: Sender < Message > ,
385- ) {
385+ ) -> bool {
386386 use crate :: app:: { FILE_SEARCH_BATCH_SIZE , FILE_SEARCH_MAX_RESULTS } ;
387387
388388 let mut reader = tokio:: io:: BufReader :: new ( stdout) ;
@@ -395,7 +395,7 @@ async fn read_mdfind_results(
395395 result = reader. read_line( & mut line) => result,
396396 _ = receiver. changed( ) => {
397397 // New query arrived — caller will handle it.
398- break ;
398+ return true ;
399399 }
400400 } ;
401401
@@ -408,7 +408,7 @@ async fn read_mdfind_results(
408408 . await
409409 . ok ( ) ;
410410 }
411- break ;
411+ return false ;
412412 }
413413 Ok ( _) => {
414414 if let Some ( app) = crate :: commands:: path_to_app ( line. trim ( ) , home_dir) {
@@ -428,10 +428,10 @@ async fn read_mdfind_results(
428428 . await
429429 . ok ( ) ;
430430 }
431- break ;
431+ return false ;
432432 }
433433 }
434- Err ( _) => break ,
434+ Err ( _) => return false ,
435435 }
436436 }
437437}
@@ -492,12 +492,14 @@ fn handle_file_search() -> impl futures::Stream<Item = Message> {
492492 assert ! ( !home_dir. is_empty( ) , "HOME must not be empty." ) ;
493493
494494 let mut child: Option < tokio:: process:: Child > = None ;
495+ let mut wait_for_change = true ;
495496
496497 loop {
497- if receiver. changed ( ) . await . is_err ( ) {
498- return ;
498+ if wait_for_change && receiver. changed ( ) . await . is_err ( ) {
499+ break ;
499500 }
500- receiver. borrow_and_update ( ) ;
501+
502+ wait_for_change = true ;
501503
502504 // Kill previous mdfind if still running.
503505 if let Some ( ref mut proc) = child {
@@ -506,7 +508,7 @@ fn handle_file_search() -> impl futures::Stream<Item = Message> {
506508 }
507509 child = None ;
508510
509- let ( query, dirs) = receiver. borrow ( ) . clone ( ) ;
511+ let ( query, dirs) = receiver. borrow_and_update ( ) . clone ( ) ;
510512 assert ! ( query. len( ) < 1024 , "Query too long." ) ;
511513
512514 if query. len ( ) < 2 {
@@ -525,28 +527,51 @@ fn handle_file_search() -> impl futures::Stream<Item = Message> {
525527 args. push ( expanded) ;
526528 }
527529
528- let spawn_result = tokio:: process:: Command :: new ( "mdfind" )
529- . args ( & args)
530- . stdout ( std:: process:: Stdio :: piped ( ) )
531- . stderr ( std:: process:: Stdio :: null ( ) )
532- . kill_on_drop ( true )
533- . spawn ( ) ;
534-
535- let mut proc = match spawn_result {
536- Ok ( p) => p,
537- Err ( err) => {
538- warn ! ( "Failed to spawn mdfind: {err}" ) ;
530+ let mut command = tokio:: process:: Command :: new ( "mdfind" ) ;
531+ command. args ( & args) ;
532+ command. stdout ( std:: process:: Stdio :: piped ( ) ) ;
533+ command. stderr ( std:: process:: Stdio :: null ( ) ) ;
534+
535+ let mut spawned = match command. spawn ( ) {
536+ Ok ( child) => child,
537+ Err ( error) => {
538+ warn ! ( "Failed to spawn mdfind: {error}" ) ;
539539 continue ;
540540 }
541541 } ;
542542
543- let stdout = match proc. stdout . take ( ) {
544- Some ( s) => s,
545- None => continue ,
543+ let stdout = match spawned. stdout . take ( ) {
544+ Some ( stdout) => stdout,
545+ None => {
546+ warn ! ( "mdfind stdout was not captured" ) ;
547+ spawned. kill ( ) . await . ok ( ) ;
548+ spawned. wait ( ) . await . ok ( ) ;
549+ continue ;
550+ }
546551 } ;
547- child = Some ( proc) ;
548552
549- read_mdfind_results ( stdout, & home_dir, & mut receiver, & mut output) . await ;
553+ child = Some ( spawned) ;
554+
555+ let canceled = read_mdfind_results ( stdout, & home_dir, & mut receiver, & mut output) . await ;
556+
557+ if let Some ( ref mut proc) = child {
558+ if canceled {
559+ proc. kill ( ) . await . ok ( ) ;
560+ }
561+ proc. wait ( ) . await . ok ( ) ;
562+ }
563+ child = None ;
564+
565+ // `read_mdfind_results` consumed the watch notification when canceled,
566+ // so process the latest query immediately.
567+ if canceled {
568+ wait_for_change = false ;
569+ }
570+ }
571+
572+ if let Some ( ref mut proc) = child {
573+ proc. kill ( ) . await . ok ( ) ;
574+ proc. wait ( ) . await . ok ( ) ;
550575 }
551576 } )
552577}
0 commit comments