Skip to content

Commit

Permalink
sync2: fptree: fix deadlock (#6475)
Browse files Browse the repository at this point in the history
## Motivation

There's a bug in FPTree causing deadlock due to recursive locking of an RWMutex.
  • Loading branch information
ivan4th committed Nov 20, 2024
1 parent 69957b2 commit 5a398cf
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions sync2/fptree/fptree.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@ func (ft *FPTree) All() rangesync.SeqResult {
func (ft *FPTree) From(from rangesync.KeyBytes, sizeHint int) rangesync.SeqResult {
ft.np.lockRead()
defer ft.np.unlockRead()
return ft.from(from, sizeHint)
}

func (ft *FPTree) from(from rangesync.KeyBytes, sizeHint int) rangesync.SeqResult {
switch {
case ft.root == noIndex:
return rangesync.EmptySeqResult()
Expand Down Expand Up @@ -690,7 +694,7 @@ func (ft *FPTree) aggregateEdge(
case ac.limit > 0:
sizeHint = min(ac.limit, sizeHint)
}
sr := ft.From(startFrom, sizeHint)
sr := ft.from(startFrom, sizeHint)
if ac.limit == 0 {
next, err := sr.First()
if err != nil {
Expand Down Expand Up @@ -1060,7 +1064,7 @@ func (ft *FPTree) startFromPrefix(ac *aggContext, p prefix) rangesync.SeqResult
k := make(rangesync.KeyBytes, ft.keyLen)
p.idAfter(k)
ft.log("startFromPrefix: p: %s idAfter: %s", p, k)
return ft.From(k, 1)
return ft.from(k, 1)
}

// nextFromPrefix return the first item that has the prefix p.
Expand Down Expand Up @@ -1106,7 +1110,7 @@ func (ft *FPTree) fingerprintInterval(x, y rangesync.KeyBytes, limit int) (fpr F
ft.log("fingerprintInterval: items %v", ac.items)
fpr.Items = ac.items
} else {
fpr.Items = ft.From(x, 1)
fpr.Items = ft.from(x, 1)
ft.log("fingerprintInterval: start from x: %v", fpr.Items)
}

Expand All @@ -1126,7 +1130,7 @@ func (ft *FPTree) fingerprintInterval(x, y rangesync.KeyBytes, limit int) (fpr F
fpr.Next, err = ft.nextFromPrefix(&ac, *ac.lastPrefix)
ft.log("fingerprintInterval: next at lastPrefix %s -> %s", *ac.lastPrefix, fpr.Next)
} else {
next, err := ft.From(y, 1).First()
next, err := ft.from(y, 1).First()
if err != nil {
return FPResult{}, err
}
Expand Down Expand Up @@ -1178,7 +1182,7 @@ func (ft *FPTree) easySplit(x, y rangesync.KeyBytes, limit int) (sr SplitResult,
middle := make(rangesync.KeyBytes, ft.keyLen)
ac.lastPrefix0.idAfter(middle)
ft.log("easySplit: lastPrefix0 %s middle %s", ac.lastPrefix0, middle)
items := ft.From(x, 1)
items := ft.from(x, 1)
part0 := FPResult{
FP: ac.fp0,
Count: ac.count0,
Expand Down

0 comments on commit 5a398cf

Please sign in to comment.