vfs: add WaitForWriters to wait until all writers have finished

This commit is contained in:
Nick Craig-Wood 2017-11-18 11:57:40 +00:00
parent 321b6da7af
commit a5b034a992
2 changed files with 49 additions and 0 deletions

View File

@ -115,6 +115,13 @@ func (f *File) delWriter(h Handle) {
f.mu.Unlock()
}
// activeWriters returns the number of writers on the file
func (f *File) activeWriters() int {
f.mu.Lock()
defer f.mu.Unlock()
return len(f.writers)
}
// ModTime returns the modified time of the file
//
// if NoModTime is set then it returns the mod time of the directory

View File

@ -248,6 +248,48 @@ func (vfs *VFS) CleanUp() error {
return vfs.cache.cleanUp()
}
// WaitForWriters sleeps until all writers have finished or
// time.Duration has elapsed
func (vfs *VFS) WaitForWriters(timeout time.Duration) {
defer fs.Trace(nil, "timeout=%v", timeout)("")
const tickTime = 1 * time.Second
deadline := time.NewTimer(timeout)
defer deadline.Stop()
tick := time.NewTimer(tickTime)
defer tick.Stop()
tick.Stop()
for {
writers := 0
vfs.root.walk("", func(d *Dir) {
fs.Debugf(d.path, "Looking for writers")
// NB d.mu is held by walk() here
for leaf, item := range d.items {
fs.Debugf(leaf, "reading active writers")
if file, ok := item.(*File); ok {
n := file.activeWriters()
if n != 0 {
fs.Debugf(file, "active writers %d", n)
}
writers += n
}
}
})
if writers == 0 {
return
}
fs.Debugf(nil, "Still %d writers active, waiting %v", writers, tickTime)
tick.Reset(tickTime)
select {
case <-tick.C:
break
case <-deadline.C:
fs.Errorf(nil, "Exiting even though %d writers are active after %v", writers, timeout)
return
}
}
}
// Root returns the root node
func (vfs *VFS) Root() (*Dir, error) {
// fs.Debugf(vfs.f, "Root()")