diff --git a/backend/cache/cache.go b/backend/cache/cache.go index ee8b04bba..0094d9b4f 100644 --- a/backend/cache/cache.go +++ b/backend/cache/cache.go @@ -23,6 +23,7 @@ import ( "github.com/ncw/rclone/fs/config/obscure" "github.com/ncw/rclone/fs/hash" "github.com/ncw/rclone/fs/walk" + "github.com/ncw/rclone/lib/atexit" "github.com/pkg/errors" "golang.org/x/net/context" "golang.org/x/time/rate" @@ -325,14 +326,14 @@ func NewFs(name, rootPath string) (fs.Fs, error) { } // Trap SIGINT and SIGTERM to close the DB handle gracefully c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) + signal.Notify(c, syscall.SIGHUP) + atexit.Register(func() { + f.StopBackgroundRunners() + }) go func() { for { s := <-c - if s == syscall.SIGINT || s == syscall.SIGTERM { - fs.Debugf(f, "Got signal: %v", s) - f.StopBackgroundRunners() - } else if s == syscall.SIGHUP { + if s == syscall.SIGHUP { fs.Infof(f, "Clearing cache from signal") f.DirCacheFlush() } @@ -1245,7 +1246,7 @@ func (f *Fs) CleanUpCache(ignoreLastTs bool) { // can be triggered from a terminate signal or from testing between runs func (f *Fs) StopBackgroundRunners() { f.cleanupChan <- false - if f.tempWritePath != "" { + if f.tempWritePath != "" && f.backgroundRunner != nil && f.backgroundRunner.isRunning() { f.backgroundRunner.close() } f.cache.Close() diff --git a/backend/cache/handle.go b/backend/cache/handle.go index 3fc84d070..f96dae4c7 100644 --- a/backend/cache/handle.go +++ b/backend/cache/handle.go @@ -561,6 +561,7 @@ type backgroundWriter struct { stateCh chan int running bool notifyCh chan BackgroundUploadState + mu sync.Mutex } func newBackgroundWriter(f *Fs) *backgroundWriter { @@ -575,6 +576,10 @@ func newBackgroundWriter(f *Fs) *backgroundWriter { func (b *backgroundWriter) close() { b.stateCh <- 2 + b.mu.Lock() + defer b.mu.Unlock() + b.running = false + } func (b *backgroundWriter) pause() { @@ -585,6 +590,12 @@ func (b *backgroundWriter) play() { b.stateCh <- 0 } +func (b *backgroundWriter) isRunning() bool { + b.mu.Lock() + defer b.mu.Unlock() + return b.running +} + func (b *backgroundWriter) notify(remote string, status int, err error) { state := BackgroundUploadState{ Remote: remote, @@ -601,7 +612,9 @@ func (b *backgroundWriter) notify(remote string, status int, err error) { func (b *backgroundWriter) run() { state := 0 for { + b.mu.Lock() b.running = true + b.mu.Unlock() select { case s := <-b.stateCh: state = s @@ -614,7 +627,6 @@ func (b *backgroundWriter) run() { time.Sleep(time.Millisecond * 500) continue case 2: - b.running = false return }