Fixed the weird crash with calling Do() recursively; woo!

This commit is contained in:
Pietro Gagliardi 2014-08-11 21:57:20 -04:00
parent 166eaeb7db
commit eb504480b1
4 changed files with 17 additions and 9 deletions

View File

@ -21,7 +21,8 @@ func Go() error {
} }
// To ensure that Do() and Stop() only do things after Go() has been called, this channel accepts the requests to issue. The issuing is done by uiissueloop() below. // To ensure that Do() and Stop() only do things after Go() has been called, this channel accepts the requests to issue. The issuing is done by uiissueloop() below.
var issuer = make(chan func()) // Notice that this is a pointer ot a function. See Do() below for details.
var issuer = make(chan *func())
// Do performs f on the main loop, as if it were an event handler. // Do performs f on the main loop, as if it were an event handler.
// It waits for f to execute before returning. // It waits for f to execute before returning.
@ -29,10 +30,14 @@ var issuer = make(chan func())
func Do(f func()) { func Do(f func()) {
done := make(chan struct{}) done := make(chan struct{})
defer close(done) defer close(done)
issuer <- func() { // THIS MUST BE A POINTER.
// Previously, the pointer was constructed within issue().
// This meant that if the Do() was stalled, the garbage collector came in and reused the pointer value too soon!
call := func() {
f() f()
done <- struct{}{} done <- struct{}{}
} }
issuer <- &call
<-done <-done
} }
@ -42,7 +47,10 @@ func Do(f func()) {
// Stop will not have an effect until any event handlers or dialog boxes presently active return. // Stop will not have an effect until any event handlers or dialog boxes presently active return.
// (TODO make sure this is the case for dialog boxes) // (TODO make sure this is the case for dialog boxes)
func Stop() { func Stop() {
issuer <- uistop // can't send this directly across issuer
go func() {
Do(uistop)
}()
} }
func uiissueloop() { func uiissueloop() {

View File

@ -31,8 +31,8 @@ func uistop() {
C.uistop() C.uistop()
} }
func issue(f func()) { func issue(f *func()) {
C.issue(unsafe.Pointer(&f)) C.issue(unsafe.Pointer(f))
} }
//export doissue //export doissue

View File

@ -34,8 +34,8 @@ func uistop() {
C.gtk_main_quit() C.gtk_main_quit()
} }
func issue(f func()) { func issue(f *func()) {
C.gdk_threads_add_idle(C.GSourceFunc(C.doissue), C.gpointer(unsafe.Pointer(&f))) C.gdk_threads_add_idle(C.GSourceFunc(C.doissue), C.gpointer(unsafe.Pointer(f)))
} }
//export doissue //export doissue

View File

@ -47,8 +47,8 @@ func uistop() {
C.PostQuitMessage(0) C.PostQuitMessage(0)
} }
func issue(f func()) { func issue(f *func()) {
C.issue(unsafe.Pointer(&f)) C.issue(unsafe.Pointer(f))
} }
func makemsgwin() error { func makemsgwin() error {