diff options
author | Simon Ser <contact@emersion.fr> | 2019-04-27 16:47:59 +0000 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-04-27 14:30:28 -0400 |
commit | 5685a176747711d0330f1251ad297b13e0621a37 (patch) | |
tree | d338db2be97f5ac412a427776167d21b04abdf99 /lib/ui/borders.go | |
parent | 9ef2a57b51601cc0e18824bbfe8026891da1a38d (diff) | |
download | aerc-5685a176747711d0330f1251ad297b13e0621a37.tar.gz |
lib/ui: introduce Invalidatable
Many Drawable implementations have their own Invalidate and OnInvalidate
functions, with an unexported onInvalidate field. However OnInvalidate and
Invalidate are usually not called in the same goroutine. This results in a race
on this field, e.g.:
Read at 0x00c000094748 by goroutine 7:
git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList.func1()
/home/simon/src/aerc2/widgets/dirlist.go:85 +0x56
git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start.func1()
/home/simon/src/aerc2/widgets/spinner.go:93 +0x1bb
Previous write at 0x00c000094748 by main goroutine:
[failed to restore the stack]
Goroutine 7 (running) created at:
git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start()
/home/simon/src/aerc2/widgets/spinner.go:46 +0x8f
git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList()
/home/simon/src/aerc2/widgets/dirlist.go:37 +0x286
git.sr.ht/~sircmpwn/aerc2/widgets.NewAccountView()
/home/simon/src/aerc2/widgets/account.go:50 +0x5ca
git.sr.ht/~sircmpwn/aerc2/widgets.NewAerc()
/home/simon/src/aerc2/widgets/aerc.go:60 +0x800
main.main()
/home/simon/src/aerc2/aerc.go:65 +0x33e
To fix this, introduce a new type, Invalidatable, which protects the field.
Unfortunately the Drawable must be passed to the callback function in
Invalidate, so we still need to re-implement this in each Invalidatable user.
Diffstat (limited to 'lib/ui/borders.go')
-rw-r--r-- | lib/ui/borders.go | 9 |
1 files changed, 2 insertions, 7 deletions
diff --git a/lib/ui/borders.go b/lib/ui/borders.go index 9b7860e4..cffd3ca3 100644 --- a/lib/ui/borders.go +++ b/lib/ui/borders.go @@ -12,6 +12,7 @@ const ( ) type Bordered struct { + Invalidatable borders uint content Drawable onInvalidate func(d Drawable) @@ -35,13 +36,7 @@ func (bordered *Bordered) Children() []Drawable { } func (bordered *Bordered) Invalidate() { - if bordered.onInvalidate != nil { - bordered.onInvalidate(bordered) - } -} - -func (bordered *Bordered) OnInvalidate(onInvalidate func(d Drawable)) { - bordered.onInvalidate = onInvalidate + bordered.DoInvalidate(bordered) } func (bordered *Bordered) Draw(ctx *Context) { |