forked from TrueCloudLab/restic
prevent deadlock in List() for B2 when b2.connections=1
This is a fix for the following situation (gh-1188): List() grabs a semaphore token upon entry, starts a goroutine, and does not release the token until the routine exits (via a defer). The goroutine iterates over the results from ListCurrentObjects(), sending them one at a time to a channel, where they are ultimately processed by be.Load(). Since be.Load() also needs a token, this will result in deadlock if b2.connections=1. This fix changes List() so that the token is only held during the call to ListCurrentObjects().
This commit is contained in:
parent
53a554c89d
commit
3304b0fcf0
1 changed files with 2 additions and 3 deletions
|
@ -307,18 +307,17 @@ func (be *b2Backend) List(ctx context.Context, t restic.FileType) <-chan string
|
|||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
be.sem.GetToken()
|
||||
|
||||
go func() {
|
||||
defer close(ch)
|
||||
defer cancel()
|
||||
defer be.sem.ReleaseToken()
|
||||
|
||||
prefix := be.Dirname(restic.Handle{Type: t})
|
||||
cur := &b2.Cursor{Prefix: prefix}
|
||||
|
||||
for {
|
||||
be.sem.GetToken()
|
||||
objs, c, err := be.bucket.ListCurrentObjects(ctx, be.listMaxItems, cur)
|
||||
be.sem.ReleaseToken()
|
||||
if err != nil && err != io.EOF {
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue