-
Notifications
You must be signed in to change notification settings - Fork 225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add windows ReadDirectoryChanges support #39
Conversation
…nsmute on request pointer. - This switches the main loop to alternate between waiting for action events and blocking on SleepEx. The SleepEx block allows completion events to fire. - This also fixes a failed transmute in the completion callback. Basically instead of using the request_p casted to &mut c_void, we need to transmute it and pass that into ReadDirectoryChangesW. Otherwise, when the completion routine attempts to transmute it back, it will be crap. - Still need to fix some todos, so this is still WIP.
…dows2 Conflicts: Cargo.toml src/lib.rs
…s closed - Most of the other watchers don't panic on send failure
- Transmute converts them back into a droppable resource
- If these occur they are internal errors, so Generic seems sufficient
…efore creating files
- Otherwise files can't be renamed/deleted!
- The file or directory must exist when watch is called, since we use its type to determine how to watch it. - File watches are essentially emulated by watching the parent directory and excluding changes to anything but the target file. This allows reuse of the ReadDirectoryChangesW API.
- Windows needs a special variant of this test to deal with its limitations. - This also modifies validate_recv to return the event list, so that the calling test can check more properties
Great to see someone finish the work I started! 👏 |
@@ -0,0 +1,306 @@ | |||
extern crate libc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems entirely unused.
@@ -6,7 +6,7 @@ authors = [ | |||
"Antti Keränen <detegr@gmail.com>", | |||
"Gilbert Röhrbein <gilbert@ifsr.de>", | |||
"Jorge Israel Peña <jorge.israel.p@gmail.com>", | |||
"Michael Maurizi <mmaurizi@azavea.com>", | |||
"Michael Maurizi <michael.maurizi@gmail.com>", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add yourself in there, too :)
- Allows final read callback to fire, so that we can destroy outstanding request memory
@passcod, I'm going to investigate an alternate fix for the shutdown memory leak that @retep998 found. The sleep I have there works for the common case, but if the completion routine isn't fired before sleep exits, it still leaks memory. So if you created lots of watchers on a busy system and then shut them down, you'd probably leak some memory. It will probably be a couple days before I can get that fix in. |
- This required adding a new channel to the watcher that allows the test to observe internal changes ("Meta Events")
- Each watcher now has a a semaphore that is used to indicate when the final completion routine is called (or a read failed) - Also added some general error handling to make the code more robust in the face of deleted watch directories, etc
- Seen it fail with 5ms
I made some good progress on that leak here: jmquigs@02bca44. I'm using semaphores to make sure that I wait for the final completion callback on each watcher. Its not part of this PR; might be better to have a separate PR since there are so many changes here already. |
unsafe extern "system" fn handle_event(error_code: u32, _bytes_written: u32, overlapped: LPOVERLAPPED) { | ||
// TODO: Use Box::from_raw when it is no longer unstable | ||
let overlapped: Box<OVERLAPPED> = mem::transmute(overlapped); | ||
let request: Box<ReadDirectoryRequest> = mem::transmute(overlapped.hEvent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the minimum Rust version is for this project, but Box::from_raw
has been stabilized as of 1.4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Latest stable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to Box::from_raw
// for our own purposes | ||
|
||
let req_buf = request.buffer.as_mut_ptr() as *mut c_void; | ||
let request_p: *mut c_void = mem::transmute(request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be Box::into_raw
- Allows errors to be returned immediately, rather than on the event channel - Use a semaphore to wake up the server so that watch doesn't have to block for up to 500ms - Add a new metaevent to let unit test check this
I don't have any more pending changes for this PR. It would be nice to add a dedup to the windows watcher are some point (its kinda spammy with writes to same file, for instance), but that should wait for another PR. |
@passcod, its fine if you aren't comfortable merging this. I'll keep the branch around in my fork anyway, since I need it for my project. |
Oh, I am totally comfortable merging this, but I don't have either the expertise to assess whether it's good code nor the setup to test it (appveyor takes care of some of that, but still). I'll probably end up merging it if nobody chimes in to tell me not to in a little bit, but I still want to give time for @retep998 and/or @maurizi to give it a look over and give me a LGTM. |
Original code by @maurizi , with some fixes by me.
Fix #4