watch: Unsubscribe from fsnotify synchronously.
Calling watcher.Remove() from the run() goroutine is now problematic, because with the change made in fsnotify/fsnotify#73 Remove() can now take an arbitrary amount of time, which means we can deadlock if run() is waiting for fsnotify to acknowledge the removal and fsnotify is trying to send an unrelated Event. So instead we now do part of the cleanup, including calling Remove(), synchronously, in the goroutine trying to unsubscribe. This fixes #75. Thanks to Aaron Beitch for the fix. Change-Id: I346c9eecc34b2378312b07b3c3efc41616b95380
This commit is contained in:
parent
f4e2250826
commit
ac5972aca8
|
@ -107,8 +107,26 @@ func remove(winfo *watchInfo) {
|
|||
delete(shared.done, winfo.fname)
|
||||
close(done)
|
||||
}
|
||||
|
||||
fname := winfo.fname
|
||||
if winfo.isCreate() {
|
||||
// Watch for new files to be created in the parent directory.
|
||||
fname = filepath.Dir(fname)
|
||||
}
|
||||
shared.watchNums[fname]--
|
||||
watchNum := shared.watchNums[fname]
|
||||
if watchNum == 0 {
|
||||
delete(shared.watchNums, fname)
|
||||
}
|
||||
shared.mux.Unlock()
|
||||
|
||||
// If we were the last ones to watch this file, unsubscribe from inotify.
|
||||
// This needs to happen after releasing the lock because fsnotify waits
|
||||
// synchronously for the kernel to acknowledge the removal of the watch
|
||||
// for this file, which causes us to deadlock if we still held the lock.
|
||||
if watchNum == 0 {
|
||||
shared.watcher.Remove(fname)
|
||||
}
|
||||
shared.remove <- winfo
|
||||
}
|
||||
|
||||
|
@ -174,19 +192,6 @@ func (shared *InotifyTracker) removeWatch(winfo *watchInfo) {
|
|||
return
|
||||
}
|
||||
|
||||
fname := winfo.fname
|
||||
if winfo.isCreate() {
|
||||
// Watch for new files to be created in the parent directory.
|
||||
fname = filepath.Dir(fname)
|
||||
}
|
||||
|
||||
shared.watchNums[fname]--
|
||||
if shared.watchNums[fname] == 0 {
|
||||
delete(shared.watchNums, fname)
|
||||
// TODO: handle error
|
||||
shared.watcher.Remove(fname)
|
||||
}
|
||||
|
||||
delete(shared.chans, winfo.fname)
|
||||
close(ch)
|
||||
|
||||
|
|
Loading…
Reference in New Issue