mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
app: ensure waiting window requests are stopped when a window closes
The Android RegisterFragment method would leak a goroutine if called after the window was destroyed. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+4
-6
@@ -27,10 +27,8 @@ type androidDriver interface {
|
||||
// and registers it as a Fragment in the Context in which the View was
|
||||
// created.
|
||||
func (w *Window) RegisterFragment(del string) {
|
||||
go func() {
|
||||
w.driverFuncs <- func() {
|
||||
d := w.driver.(androidDriver)
|
||||
d.RegisterFragment(del)
|
||||
}
|
||||
}()
|
||||
w.driverDo(func() {
|
||||
d := w.driver.(androidDriver)
|
||||
d.RegisterFragment(del)
|
||||
})
|
||||
}
|
||||
|
||||
+16
-1
@@ -37,6 +37,8 @@ type Window struct {
|
||||
invalidates chan struct{}
|
||||
frames chan *op.Ops
|
||||
frameAck chan struct{}
|
||||
// dead is closed when the window is destroyed.
|
||||
dead chan struct{}
|
||||
|
||||
stage system.Stage
|
||||
animating bool
|
||||
@@ -96,6 +98,7 @@ func NewWindow(options ...Option) *Window {
|
||||
frames: make(chan *op.Ops),
|
||||
frameAck: make(chan struct{}),
|
||||
driverFuncs: make(chan func()),
|
||||
dead: make(chan struct{}),
|
||||
}
|
||||
w.callbacks.w = w
|
||||
go w.run(opts)
|
||||
@@ -188,6 +191,17 @@ func (w *Window) Invalidate() {
|
||||
}
|
||||
}
|
||||
|
||||
// driverDo calls f as soon as the window has a valid driver attached,
|
||||
// or does nothing if the window is destroyed while waiting.
|
||||
func (w *Window) driverDo(f func()) {
|
||||
go func() {
|
||||
select {
|
||||
case w.driverFuncs <- f:
|
||||
case <-w.dead:
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (w *Window) updateAnimation() {
|
||||
animate := false
|
||||
if w.delayedDraw != nil {
|
||||
@@ -236,6 +250,7 @@ func (w *Window) destroy(err error) {
|
||||
// Ack the current event.
|
||||
w.ack <- struct{}{}
|
||||
w.out <- system.DestroyEvent{Err: err}
|
||||
close(w.dead)
|
||||
for e := range w.in {
|
||||
w.ack <- struct{}{}
|
||||
if _, ok := e.(system.DestroyEvent); ok {
|
||||
@@ -274,7 +289,7 @@ func (w *Window) run(opts *window.Options) {
|
||||
return
|
||||
}
|
||||
for {
|
||||
var driverFuncs chan func() = nil
|
||||
var driverFuncs chan func()
|
||||
if w.driver != nil {
|
||||
driverFuncs = w.driverFuncs
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user