@@ -33,7 +33,7 @@ use windows_sys::Win32::Storage::FileSystem::{
33
33
FILE_SHARE_WRITE , OPEN_EXISTING ,
34
34
} ;
35
35
use windows_sys:: Win32 :: System :: Threading :: {
36
- CreateSemaphoreW , ReleaseSemaphore , WaitForSingleObject , WaitForSingleObjectEx , INFINITE ,
36
+ CreateSemaphoreW , ReleaseSemaphore , WaitForSingleObjectEx , INFINITE ,
37
37
} ;
38
38
use windows_sys:: Win32 :: System :: IO :: { CancelIo , OVERLAPPED } ;
39
39
@@ -55,6 +55,12 @@ struct ReadDirectoryRequest {
55
55
action_tx : Sender < Action > ,
56
56
}
57
57
58
+ impl ReadDirectoryRequest {
59
+ fn unwatch ( & self ) {
60
+ let _ = self . action_tx . send ( Action :: Unwatch ( self . data . dir . clone ( ) ) ) ;
61
+ }
62
+ }
63
+
58
64
enum Action {
59
65
Watch ( PathBuf , RecursiveMode ) ,
60
66
Unwatch ( PathBuf ) ,
@@ -330,21 +336,34 @@ unsafe extern "system" fn handle_event(
330
336
let overlapped: Box < OVERLAPPED > = Box :: from_raw ( overlapped) ;
331
337
let request: Box < ReadDirectoryRequest > = Box :: from_raw ( overlapped. hEvent as * mut _ ) ;
332
338
333
- if error_code == ERROR_OPERATION_ABORTED {
334
- // received when dir is unwatched or watcher is shutdown; return and let overlapped/request
335
- // get drop-cleaned
336
- ReleaseSemaphore ( request. data . complete_sem , 1 , ptr:: null_mut ( ) ) ;
337
- return ;
338
- }
339
-
340
- if error_code == ERROR_ACCESS_DENIED {
341
- // This could hanppen when the watched directory is deleted or trahsed, first check if it's the case.
342
- // If so, unwatch the directory and return.
343
- if !request. data . dir . exists ( ) {
344
- request
345
- . action_tx
346
- . send ( Action :: Unwatch ( request. data . dir . clone ( ) ) )
347
- . ok ( ) ;
339
+ match error_code {
340
+ ERROR_OPERATION_ABORTED => {
341
+ // received when dir is unwatched or watcher is shutdown, or directory has been deleted
342
+ // check if the directory still exists, if not, unwatch it
343
+ if !request. data . dir . exists ( ) {
344
+ request. unwatch ( ) ;
345
+ }
346
+ // return and let overlapped/request get drop-cleaned
347
+ ReleaseSemaphore ( request. data . complete_sem , 1 , ptr:: null_mut ( ) ) ;
348
+ return ;
349
+ }
350
+ ERROR_ACCESS_DENIED => {
351
+ // This could hanppen when the watched directory is deleted or trahsed, first check if it's the case.
352
+ // If so, unwatch the directory and return, otherwise, continue to handle the event.
353
+ if !request. data . dir . exists ( ) {
354
+ request. unwatch ( ) ;
355
+ ReleaseSemaphore ( request. data . complete_sem , 1 , ptr:: null_mut ( ) ) ;
356
+ return ;
357
+ }
358
+ }
359
+ ERROR_SUCCESS => { }
360
+ _ => {
361
+ log:: error!(
362
+ "Unknown error in ReadDirectoryChangesW for directory {}: {}" ,
363
+ request. data. dir. display( ) ,
364
+ error_code
365
+ ) ;
366
+ request. unwatch ( ) ;
348
367
ReleaseSemaphore ( request. data . complete_sem , 1 , ptr:: null_mut ( ) ) ;
349
368
return ;
350
369
}
0 commit comments