fix deadlock with searchbar

This commit is contained in:
Drew Weymouth
2022-12-27 19:24:24 -08:00
parent 598715553f
commit 7353fa5d37
+30 -35
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) { }
select { }
case <-ctx.Done():
b.searchTimerLock.Lock() func (b *BrowsingPane) waitAndSearch() {
defer b.searchTimerLock.Unlock() t := time.NewTicker(200 * time.Millisecond)
b.searchTimer = nil var getReadyToSearch bool
case <-trigger: var done bool
for !done {
select {
case <-t.C:
b.pendingSearchLock.Lock()
if b.pendingSearch {
getReadyToSearch = true
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
} }
}(ctx, b.searchTimer.C) b.pendingSearchLock.Unlock()
} 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)
}