mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 08:46:24 +08:00
vfs: add WaitForWriters to wait until all writers have finished
This commit is contained in:
parent
321b6da7af
commit
a5b034a992
|
@ -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
|
||||
|
|
42
vfs/vfs.go
42
vfs/vfs.go
|
@ -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()")
|
||||
|
|
Loading…
Reference in New Issue
Block a user