fix deadlock with searchbar

This commit is contained in:
Drew Weymouth
2022-12-27 19:24:24 -08:00
parent 598715553f
commit 7353fa5d37
+29 -34
View File
@@ -24,8 +24,9 @@ type BrowsingPane struct {
widget.BaseWidget widget.BaseWidget
searchBar *searchField searchBar *searchField
searchTimer *time.Timer pendingSearchLock sync.Mutex
searchTimerLock sync.Mutex pendingSearch bool
searchGoroutine bool
cancelPendingSearch context.CancelFunc cancelPendingSearch context.CancelFunc
curPage Page curPage Page
@@ -138,33 +139,37 @@ func (b *BrowsingPane) SetPage(p Page) {
func (b *BrowsingPane) onSearchTextChanged(text string) { func (b *BrowsingPane) onSearchTextChanged(text string) {
if text == "" { if text == "" {
if b.cancelPendingSearch != nil {
b.cancelPendingSearch()
b.cancelPendingSearch = nil
}
b.sendSearch("") b.sendSearch("")
return
} }
b.searchTimerLock.Lock() b.pendingSearchLock.Lock()
defer b.searchTimerLock.Unlock() defer b.pendingSearchLock.Unlock()
if b.searchTimer == nil { b.pendingSearch = true
ctx, cancel := context.WithCancel(context.Background()) if !b.searchGoroutine {
b.cancelPendingSearch = cancel go b.waitAndSearch()
b.searchTimer = time.NewTimer(200 * time.Millisecond) b.searchGoroutine = true
go func(ctx context.Context, trigger <-chan time.Time) { }
}
func (b *BrowsingPane) waitAndSearch() {
t := time.NewTicker(200 * time.Millisecond)
var getReadyToSearch bool
var done bool
for !done {
select { select {
case <-ctx.Done(): case <-t.C:
b.searchTimerLock.Lock() b.pendingSearchLock.Lock()
defer b.searchTimerLock.Unlock() if b.pendingSearch {
b.searchTimer = nil getReadyToSearch = true
case <-trigger: b.pendingSearch = false
} else if getReadyToSearch {
b.sendSearch(b.searchBar.Text) b.sendSearch(b.searchBar.Text)
b.searchTimerLock.Lock() t.Stop()
defer b.searchTimerLock.Unlock() b.searchGoroutine = false
b.searchTimer = nil done = true
}
b.pendingSearchLock.Unlock()
} }
}(ctx, b.searchTimer.C)
} else {
b.resetSearchTimer(200 * time.Millisecond)
} }
} }
@@ -177,13 +182,3 @@ func (b *BrowsingPane) sendSearch(query string) {
func (b *BrowsingPane) CreateRenderer() fyne.WidgetRenderer { func (b *BrowsingPane) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(b.container) return widget.NewSimpleRenderer(b.container)
} }
func (b *BrowsingPane) resetSearchTimer(d time.Duration) {
if b.searchTimer == nil {
return
}
if !b.searchTimer.Stop() {
<-b.searchTimer.C
}
b.searchTimer.Reset(d)
}