Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wait for goroutines to finish when firing a change to an app preferences #2246

Merged
merged 7 commits into from May 24, 2021
21 changes: 15 additions & 6 deletions internal/preferences.go
Expand Up @@ -11,17 +11,22 @@ type InMemoryPreferences struct {
values map[string]interface{}
lock sync.RWMutex
changeListeners []func()
waitGroup *sync.WaitGroup
}

// Declare conformity with Preferences interface
var _ fyne.Preferences = (*InMemoryPreferences)(nil)

// AddChangeListener allows code to be notified when some preferences change. This will fire on any update.
// listener should not try to write values
s77rt marked this conversation as resolved.
Show resolved Hide resolved
func (p *InMemoryPreferences) AddChangeListener(listener func()) {
p.lock.Lock()
defer p.lock.Unlock()

p.changeListeners = append(p.changeListeners, listener)
p.changeListeners = append(p.changeListeners, func() {
defer p.waitGroup.Done()
s77rt marked this conversation as resolved.
Show resolved Hide resolved
s77rt marked this conversation as resolved.
Show resolved Hide resolved
listener()
})
}

// ReadValues provides read access to the underlying value map - for internal use only...
Expand Down Expand Up @@ -67,12 +72,15 @@ func (p *InMemoryPreferences) remove(key string) {
}

func (p *InMemoryPreferences) fireChange() {
p.lock.Lock()
defer p.lock.Unlock()
p.lock.RLock()
defer p.lock.RUnlock()

for _, l := range p.changeListeners {
p.waitGroup.Add(1)
s77rt marked this conversation as resolved.
Show resolved Hide resolved
go l()
}

p.waitGroup.Wait()
}

// Bool looks up a boolean value for the key
Expand Down Expand Up @@ -178,7 +186,8 @@ func (p *InMemoryPreferences) RemoveValue(key string) {

// NewInMemoryPreferences creates a new preferences implementation stored in memory
func NewInMemoryPreferences() *InMemoryPreferences {
p := &InMemoryPreferences{}
p.values = make(map[string]interface{})
return p
return &InMemoryPreferences{
values: make(map[string]interface{}),
waitGroup: &sync.WaitGroup{},
s77rt marked this conversation as resolved.
Show resolved Hide resolved
}
}