mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55: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
|
// and registers it as a Fragment in the Context in which the View was
|
||||||
// created.
|
// created.
|
||||||
func (w *Window) RegisterFragment(del string) {
|
func (w *Window) RegisterFragment(del string) {
|
||||||
go func() {
|
w.driverDo(func() {
|
||||||
w.driverFuncs <- func() {
|
d := w.driver.(androidDriver)
|
||||||
d := w.driver.(androidDriver)
|
d.RegisterFragment(del)
|
||||||
d.RegisterFragment(del)
|
})
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-1
@@ -37,6 +37,8 @@ type Window struct {
|
|||||||
invalidates chan struct{}
|
invalidates chan struct{}
|
||||||
frames chan *op.Ops
|
frames chan *op.Ops
|
||||||
frameAck chan struct{}
|
frameAck chan struct{}
|
||||||
|
// dead is closed when the window is destroyed.
|
||||||
|
dead chan struct{}
|
||||||
|
|
||||||
stage system.Stage
|
stage system.Stage
|
||||||
animating bool
|
animating bool
|
||||||
@@ -96,6 +98,7 @@ func NewWindow(options ...Option) *Window {
|
|||||||
frames: make(chan *op.Ops),
|
frames: make(chan *op.Ops),
|
||||||
frameAck: make(chan struct{}),
|
frameAck: make(chan struct{}),
|
||||||
driverFuncs: make(chan func()),
|
driverFuncs: make(chan func()),
|
||||||
|
dead: make(chan struct{}),
|
||||||
}
|
}
|
||||||
w.callbacks.w = w
|
w.callbacks.w = w
|
||||||
go w.run(opts)
|
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() {
|
func (w *Window) updateAnimation() {
|
||||||
animate := false
|
animate := false
|
||||||
if w.delayedDraw != nil {
|
if w.delayedDraw != nil {
|
||||||
@@ -236,6 +250,7 @@ func (w *Window) destroy(err error) {
|
|||||||
// Ack the current event.
|
// Ack the current event.
|
||||||
w.ack <- struct{}{}
|
w.ack <- struct{}{}
|
||||||
w.out <- system.DestroyEvent{Err: err}
|
w.out <- system.DestroyEvent{Err: err}
|
||||||
|
close(w.dead)
|
||||||
for e := range w.in {
|
for e := range w.in {
|
||||||
w.ack <- struct{}{}
|
w.ack <- struct{}{}
|
||||||
if _, ok := e.(system.DestroyEvent); ok {
|
if _, ok := e.(system.DestroyEvent); ok {
|
||||||
@@ -274,7 +289,7 @@ func (w *Window) run(opts *window.Options) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
var driverFuncs chan func() = nil
|
var driverFuncs chan func()
|
||||||
if w.driver != nil {
|
if w.driver != nil {
|
||||||
driverFuncs = w.driverFuncs
|
driverFuncs = w.driverFuncs
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user