actually drop watcher, use parking_lot::Mutex

This commit is contained in:
Bernardo 2019-01-19 01:15:22 +01:00 committed by Aleksey Kladov
parent f181e36a44
commit fb1d748a2c
3 changed files with 19 additions and 9 deletions

1
Cargo.lock generated
View file

@ -1042,6 +1042,7 @@ dependencies = [
"ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.6 (git+https://github.com/vemoo/notify/?branch=v4-legacy)", "notify 4.0.6 (git+https://github.com/vemoo/notify/?branch=v4-legacy)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ra_arena 0.1.0", "ra_arena 0.1.0",
"relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -14,6 +14,7 @@ log = "0.4.6"
notify = { git = "https://github.com/vemoo/notify/", branch = "v4-legacy" } notify = { git = "https://github.com/vemoo/notify/", branch = "v4-legacy" }
ignore = "0.4" ignore = "0.4"
drop_bomb = "0.1.0" drop_bomb = "0.1.0"
parking_lot = "0.7.0"
thread_worker = { path = "../thread_worker" } thread_worker = { path = "../thread_worker" }
ra_arena = { path = "../ra_arena" } ra_arena = { path = "../ra_arena" }

View file

@ -3,15 +3,16 @@ use crossbeam_channel::Sender;
use drop_bomb::DropBomb; use drop_bomb::DropBomb;
use ignore; use ignore;
use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as NotifyWatcher}; use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as NotifyWatcher};
use parking_lot::Mutex;
use std::{ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::{mpsc, Arc, Mutex}, sync::{mpsc, Arc},
thread, thread,
time::Duration, time::Duration,
}; };
pub struct Watcher { pub struct Watcher {
watcher: Arc<Mutex<RecommendedWatcher>>, watcher: Arc<Mutex<Option<RecommendedWatcher>>>,
thread: thread::JoinHandle<()>, thread: thread::JoinHandle<()>,
bomb: DropBomb, bomb: DropBomb,
} }
@ -27,7 +28,7 @@ pub enum WatcherChange {
fn handle_change_event( fn handle_change_event(
ev: DebouncedEvent, ev: DebouncedEvent,
sender: &Sender<io::Task>, sender: &Sender<io::Task>,
watcher: &Arc<Mutex<RecommendedWatcher>>, watcher: &Arc<Mutex<Option<RecommendedWatcher>>>,
) -> Result<(), Box<std::error::Error>> { ) -> Result<(), Box<std::error::Error>> {
match ev { match ev {
DebouncedEvent::NoticeWrite(_) DebouncedEvent::NoticeWrite(_)
@ -69,16 +70,23 @@ fn watch_one(watcher: &mut RecommendedWatcher, path: &Path) {
} }
} }
fn watch_recursive(watcher: &Arc<Mutex<RecommendedWatcher>>, path: &Path) { fn watch_recursive(watcher: &Arc<Mutex<Option<RecommendedWatcher>>>, path: &Path) {
log::debug!("watch_recursive \"{}\"", path.display()); log::debug!("watch_recursive \"{}\"", path.display());
let mut w = watcher.lock().unwrap(); let mut watcher = watcher.lock();
let mut watcher = match *watcher {
Some(ref mut watcher) => watcher,
None => {
// watcher has been dropped
return;
}
};
// TODO it seems path itself isn't checked against ignores // TODO it seems path itself isn't checked against ignores
// check if path should be ignored before walking it // check if path should be ignored before walking it
for res in ignore::Walk::new(path) { for res in ignore::Walk::new(path) {
match res { match res {
Ok(entry) => { Ok(entry) => {
if entry.path().is_dir() { if entry.path().is_dir() {
watch_one(&mut w, entry.path()); watch_one(&mut watcher, entry.path());
} }
} }
Err(e) => log::warn!("watcher error: {}", e), Err(e) => log::warn!("watcher error: {}", e),
@ -91,10 +99,10 @@ impl Watcher {
output_sender: Sender<io::Task>, output_sender: Sender<io::Task>,
) -> Result<Watcher, Box<std::error::Error>> { ) -> Result<Watcher, Box<std::error::Error>> {
let (input_sender, input_receiver) = mpsc::channel(); let (input_sender, input_receiver) = mpsc::channel();
let watcher = Arc::new(Mutex::new(notify::watcher( let watcher = Arc::new(Mutex::new(Some(notify::watcher(
input_sender, input_sender,
Duration::from_millis(250), Duration::from_millis(250),
)?)); )?)));
let w = watcher.clone(); let w = watcher.clone();
let thread = thread::spawn(move || { let thread = thread::spawn(move || {
input_receiver input_receiver
@ -116,7 +124,7 @@ impl Watcher {
pub fn shutdown(mut self) -> thread::Result<()> { pub fn shutdown(mut self) -> thread::Result<()> {
self.bomb.defuse(); self.bomb.defuse();
drop(self.watcher); drop(self.watcher.lock().take());
let res = self.thread.join(); let res = self.thread.join();
match &res { match &res {
Ok(()) => log::info!("... Watcher terminated with ok"), Ok(()) => log::info!("... Watcher terminated with ok"),