app: let drivers control Window directly

Before this change, Window driver callbacks would all go through
channels to be processed by Window.run. However, Window.run may call
into the driver, which again may invoke a Window callback. These
re-entrant calls have been a source of deadlocks and subtle errors,
resulting in increasingly complex channel logic. This change eliminates
the goroutine split between Window and the driver, allowing callbacks
between Window and the driver without restrictions.

The goroutine split between Window and the driver is historical and
was meant to tame the complicated callback logic of drivers into a nice
for-select loop. However, the complexity isn't worth the gain, and there is
no concurrency concerns because there is always a 1:1 correspondance between
a driver goroutine and its Window object.

Fixes: https://todo.sr.ht/~eliasnaur/gio/329
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2022-01-04 14:48:38 +01:00
parent 72b2f2c1bf
commit 4f5baa9a51
2 changed files with 199 additions and 328 deletions
+3 -6
View File
@@ -165,6 +165,7 @@ type window struct {
hoverID router.SemanticID
rootID router.SemanticID
focusID router.SemanticID
diffs []router.SemanticID
}
}
@@ -856,12 +857,8 @@ func (w *window) draw(env *C.JNIEnv, sync bool) {
w.semantic.rootID = newR
callVoidMethod(env, w.view, gioView.sendA11yChange, jvalue(w.virtualIDFor(newR)))
}
diffs := w.callbacks.RequestSemanticDiffs()
for {
id := <-diffs
if id == 0 {
break
}
w.semantic.diffs = w.callbacks.AppendSemanticDiffs(w.semantic.diffs[:0])
for _, id := range w.semantic.diffs {
callVoidMethod(env, w.view, gioView.sendA11yChange, jvalue(w.virtualIDFor(id)))
}
}