mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55:40 +00:00
app: ensure no window wakeups are in flight when destroying it
When a window is destroyed, it is no longer valid to call its wakeup method. Thanks to Jack Mordaunt for identifying the race. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+7
-4
@@ -62,6 +62,7 @@ type Window struct {
|
|||||||
out chan event.Event
|
out chan event.Event
|
||||||
frames chan *op.Ops
|
frames chan *op.Ops
|
||||||
frameAck chan struct{}
|
frameAck chan struct{}
|
||||||
|
destroy chan struct{}
|
||||||
// dead is closed when the window is destroyed.
|
// dead is closed when the window is destroyed.
|
||||||
dead chan struct{}
|
dead chan struct{}
|
||||||
|
|
||||||
@@ -155,6 +156,7 @@ func NewWindow(options ...Option) *Window {
|
|||||||
driverFuncs: make(chan func(d driver), 1),
|
driverFuncs: make(chan func(d driver), 1),
|
||||||
wakeups: make(chan struct{}, 1),
|
wakeups: make(chan struct{}, 1),
|
||||||
wakeupFuncs: make(chan func()),
|
wakeupFuncs: make(chan func()),
|
||||||
|
destroy: make(chan struct{}),
|
||||||
dead: make(chan struct{}),
|
dead: make(chan struct{}),
|
||||||
options: make(chan []Option, 1),
|
options: make(chan []Option, 1),
|
||||||
actions: make(chan system.Action, 1),
|
actions: make(chan system.Action, 1),
|
||||||
@@ -860,8 +862,8 @@ func (w *Window) processEvent(d driver, e event.Event) bool {
|
|||||||
if err := w.validateAndProcess(d, viewSize, e2.Sync, wrapper, signal); err != nil {
|
if err := w.validateAndProcess(d, viewSize, e2.Sync, wrapper, signal); err != nil {
|
||||||
w.destroyGPU()
|
w.destroyGPU()
|
||||||
w.out <- system.DestroyEvent{Err: err}
|
w.out <- system.DestroyEvent{Err: err}
|
||||||
close(w.dead)
|
|
||||||
close(w.out)
|
close(w.out)
|
||||||
|
w.destroy <- struct{}{}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
w.processFrame(d, frameStart)
|
w.processFrame(d, frameStart)
|
||||||
@@ -869,8 +871,8 @@ func (w *Window) processEvent(d driver, e event.Event) bool {
|
|||||||
case system.DestroyEvent:
|
case system.DestroyEvent:
|
||||||
w.destroyGPU()
|
w.destroyGPU()
|
||||||
w.out <- e2
|
w.out <- e2
|
||||||
close(w.dead)
|
|
||||||
close(w.out)
|
close(w.out)
|
||||||
|
w.destroy <- struct{}{}
|
||||||
case ViewEvent:
|
case ViewEvent:
|
||||||
w.out <- e2
|
w.out <- e2
|
||||||
w.waitAck(d)
|
w.waitAck(d)
|
||||||
@@ -917,8 +919,8 @@ func (w *Window) processEvent(d driver, e event.Event) bool {
|
|||||||
func (w *Window) run(options []Option) {
|
func (w *Window) run(options []Option) {
|
||||||
if err := newWindow(&w.callbacks, options); err != nil {
|
if err := newWindow(&w.callbacks, options); err != nil {
|
||||||
w.out <- system.DestroyEvent{Err: err}
|
w.out <- system.DestroyEvent{Err: err}
|
||||||
close(w.dead)
|
|
||||||
close(w.out)
|
close(w.out)
|
||||||
|
w.destroy <- struct{}{}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var wakeup func()
|
var wakeup func()
|
||||||
@@ -940,7 +942,8 @@ func (w *Window) run(options []Option) {
|
|||||||
timer.Stop()
|
timer.Stop()
|
||||||
}
|
}
|
||||||
timer = time.NewTimer(time.Until(t))
|
timer = time.NewTimer(time.Until(t))
|
||||||
case <-w.dead:
|
case <-w.destroy:
|
||||||
|
close(w.dead)
|
||||||
return
|
return
|
||||||
case <-timeC:
|
case <-timeC:
|
||||||
select {
|
select {
|
||||||
|
|||||||
Reference in New Issue
Block a user