Ensure that the lock cleanup handler is run after the global one

cleanup handlers run in the order in which they are added. As Go calls
init() functions in lexical order, the cleanup handler from global.go
was registered before that from lock.go, which is the correct order.

Make this order explicit to ensure that this won't break accidentally.
This commit is contained in:
Michael Eischer 2020-08-09 13:54:39 +02:00
parent c6fd13425b
commit d72181c8c1
2 changed files with 9 additions and 4 deletions

View File

@ -98,6 +98,8 @@ func init() {
var cancel context.CancelFunc
globalOptions.ctx, cancel = context.WithCancel(context.Background())
AddCleanupHandler(func() error {
// Must be called before the unlock cleanup handler to ensure that the latter is
// not blocked due to limited number of backend connections, see #1434
cancel()
return nil
})

View File

@ -16,6 +16,7 @@ var globalLocks struct {
cancelRefresh chan struct{}
refreshWG sync.WaitGroup
sync.Mutex
sync.Once
}
func lockRepo(ctx context.Context, repo *repository.Repository) (*restic.Lock, error) {
@ -27,6 +28,12 @@ func lockRepoExclusive(ctx context.Context, repo *repository.Repository) (*resti
}
func lockRepository(ctx context.Context, repo *repository.Repository, exclusive bool) (*restic.Lock, error) {
// make sure that a repository is unlocked properly and after cancel() was
// called by the cleanup handler in global.go
globalLocks.Do(func() {
AddCleanupHandler(unlockAll)
})
lockFn := restic.NewLock
if exclusive {
lockFn = restic.NewExclusiveLock
@ -128,7 +135,3 @@ func unlockAll() error {
return nil
}
func init() {
AddCleanupHandler(unlockAll)
}