diff --git a/redo/uitask.go b/redo/uitask.go index 32f8faf..7231220 100644 --- a/redo/uitask.go +++ b/redo/uitask.go @@ -39,6 +39,7 @@ func uitask() { var stall = make(chan struct{}) // This is the common code for running an event. +// It runs on the main thread without a message pump; it provides its own. // TODO // - define event // - figure out how to return values from event handlers @@ -50,7 +51,26 @@ func doevent(e event) { close(c) }() for req := range c { - issue(req) + // note: this is perform, not issue! + // doevent runs on the main thread without a message pump! + perform(req) } - stall <- struct{}{} // leave event handler + // leave the event handler; leave it only after returning from an event handler so we must issue it like a normal Request + issue(&Request{ + op: func() { + stall <- struct{}{} + }, + // unfortunately, closing a nil channel causes a panic + // therefore, we have to make a dummy channel + // TODO add conditional checks to the request handler instead? + resp: make(chan interface{}), + }) +} + +// Common code for performing a Request. +// This should run on the main thread. +// Implementations of issue() should call this. +func perform(req *Request) { + req.op() + close(req.resp) } diff --git a/redo/uitask_unix.go b/redo/uitask_unix.go index 69e2350..e371303 100644 --- a/redo/uitask_unix.go +++ b/redo/uitask_unix.go @@ -28,7 +28,6 @@ func issue(req *Request) { //export doissue func doissue(data C.gpointer) C.gboolean { req := (*Request)(unsafe.Pointer(data)) - req.op() - close(req.resp) + perform(req) return C.FALSE // don't repeat }