Skip to content

Commit

Permalink
fix race condition index out of bound crash in gridview
Browse files Browse the repository at this point in the history
  • Loading branch information
dweymouth committed May 11, 2023
1 parent 0a20299 commit b2dce99
Showing 1 changed file with 30 additions and 20 deletions.
50 changes: 30 additions & 20 deletions ui/widgets/gridview.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ func (g *GridView) Clear() {
func (g *GridView) Reset(iter GridViewIterator) {
g.itemsMutex.Lock()
g.items = nil
g.itemsMutex.Unlock()
g.fetching = false
g.done = false
g.highestShown = 0
g.iter = iter
g.itemsMutex.Unlock()
g.fetchMoreItems(36)
}

Expand Down Expand Up @@ -194,8 +194,13 @@ func (g *GridView) doUpdateItemCard(itemIdx int, card *GridViewItem) {
if itemIdx > g.highestShown {
g.highestShown = itemIdx
}
var item GridViewItemModel
g.itemsMutex.RLock()
item := g.items[itemIdx]
// itemIdx can rarely be out of range if the data is being updated
// as the view is requested to refresh
if itemIdx < len(g.items) {
item = g.items[itemIdx]
}
g.itemsMutex.RUnlock()
if card.PrevID == item.ID {
// nothing to do
Expand All @@ -208,26 +213,31 @@ func (g *GridView) doUpdateItemCard(itemIdx int, card *GridViewItem) {
card.ImgLoadCancel()
card.ImgLoadCancel = nil
}
if img, ok := g.imageFetcher.GetCoverThumbnailFromCache(item.CoverArtID); ok {
card.Cover.SetImage(img)
if item.CoverArtID != "" {
if img, ok := g.imageFetcher.GetCoverThumbnailFromCache(item.CoverArtID); ok {
card.Cover.SetImage(img)
} else {
card.Cover.SetImageResource(res.ResAlbumplaceholderPng)
// asynchronously fetch cover image
ctx, cancel := context.WithCancel(context.Background())
card.ImgLoadCancel = cancel
go func(ctx context.Context) {
i, err := g.imageFetcher.GetCoverThumbnail(item.CoverArtID)
select {
case <-ctx.Done():
return
default:
if err == nil {
card.Cover.SetImage(i)
} else {
log.Printf("error fetching image: %s", err.Error())
}
}
}(ctx)
}
} else {
// use the placeholder image for an item that has no cover art ID
card.Cover.SetImageResource(res.ResAlbumplaceholderPng)
// asynchronously fetch cover image
ctx, cancel := context.WithCancel(context.Background())
card.ImgLoadCancel = cancel
go func(ctx context.Context) {
i, err := g.imageFetcher.GetCoverThumbnail(item.CoverArtID)
select {
case <-ctx.Done():
return
default:
if err == nil {
card.Cover.SetImage(i)
} else {
log.Printf("error fetching image: %s", err.Error())
}
}
}(ctx)
}

// if user has scrolled near the bottom, fetch more
Expand Down

0 comments on commit b2dce99

Please sign in to comment.