mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-24 18:02:02 +01:00
restorable: Bug fix: Guard images by mutex
The map must be guarded by mutex since this can be accessed by multiple goroutines, including finalizer goroutine. Fixes #820
This commit is contained in:
parent
6906ea1c4f
commit
7967f68073
@ -16,6 +16,7 @@ package restorable
|
||||
|
||||
import (
|
||||
"image"
|
||||
"sync"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/graphicscommand"
|
||||
)
|
||||
@ -42,6 +43,8 @@ func EnableRestoringForTesting() {
|
||||
type images struct {
|
||||
images map[*Image]struct{}
|
||||
lastTarget *Image
|
||||
|
||||
m sync.Mutex
|
||||
}
|
||||
|
||||
// theImages represents the images for the current process.
|
||||
@ -72,8 +75,15 @@ func Restore() error {
|
||||
}
|
||||
|
||||
func Images() []image.Image {
|
||||
return theImages.images()
|
||||
}
|
||||
|
||||
func (i *images) images() []image.Image {
|
||||
i.m.Lock()
|
||||
defer i.m.Unlock()
|
||||
|
||||
var imgs []image.Image
|
||||
for img := range theImages.images {
|
||||
for img := range i.images {
|
||||
if img.volatile {
|
||||
continue
|
||||
}
|
||||
@ -103,21 +113,27 @@ func Images() []image.Image {
|
||||
|
||||
// add adds img to the images.
|
||||
func (i *images) add(img *Image) {
|
||||
i.m.Lock()
|
||||
i.images[img] = struct{}{}
|
||||
i.m.Unlock()
|
||||
}
|
||||
|
||||
// remove removes img from the images.
|
||||
func (i *images) remove(img *Image) {
|
||||
i.m.Lock()
|
||||
i.makeStaleIfDependingOnImpl(img)
|
||||
delete(i.images, img)
|
||||
i.m.Unlock()
|
||||
}
|
||||
|
||||
// resolveStaleImages resolves stale images.
|
||||
func (i *images) resolveStaleImages() {
|
||||
i.m.Lock()
|
||||
i.lastTarget = nil
|
||||
for img := range i.images {
|
||||
img.resolveStale()
|
||||
}
|
||||
i.m.Unlock()
|
||||
}
|
||||
|
||||
// makeStaleIfDependingOn makes all the images stale that depend on target.
|
||||
@ -125,8 +141,10 @@ func (i *images) resolveStaleImages() {
|
||||
// When target is changed, all images depending on target can't be restored with target.
|
||||
// makeStaleIfDependingOn is called in such situation.
|
||||
func (i *images) makeStaleIfDependingOn(target *Image) {
|
||||
i.m.Lock()
|
||||
// Avoid defer for performance
|
||||
i.makeStaleIfDependingOnImpl(target)
|
||||
i.m.Unlock()
|
||||
}
|
||||
|
||||
func (i *images) makeStaleIfDependingOnImpl(target *Image) {
|
||||
@ -150,6 +168,9 @@ func (i *images) restore() error {
|
||||
panic("restorable: restore cannot be called when restoring is disabled")
|
||||
}
|
||||
|
||||
i.m.Lock()
|
||||
defer i.m.Unlock()
|
||||
|
||||
// Dispose image explicitly
|
||||
for img := range i.images {
|
||||
img.image.Dispose()
|
||||
|
Loading…
Reference in New Issue
Block a user