Removed ensureMainThread() now that the latest Go has a guarantee (which was always true) about the main thread given runtime.LockOSThread() in init().

This commit is contained in:
Pietro Gagliardi 2018-08-11 16:10:47 -04:00
parent 6c3bda44d3
commit dc108a5d4d
6 changed files with 11 additions and 46 deletions

View File

@ -3,21 +3,5 @@
package ui
// #cgo CFLAGS: -mmacosx-version-min=10.8 -DMACOSX_DEPLOYMENT_TARGET=10.8
// #cgo LDFLAGS: ${SRCDIR}/libui_darwin_amd64.a -framework Foundation -framework AppKit -lpthread -mmacosx-version-min=10.8
// #include <CoreFoundation/CoreFoundation.h>
// #include <pthread.h>
// extern void _CFRunLoopSetCurrent(CFRunLoopRef);
// extern pthread_t _CFMainPThread;
// #cgo LDFLAGS: ${SRCDIR}/libui_darwin_amd64.a -framework Foundation -framework AppKit -mmacosx-version-min=10.8
import "C"
// OS X cares very deeply if we don't run on the very first thread the OS creates
// why? who knows. it's stupid and completely indefensible. let's use undocumented APIs to get around it.
// apple uses them too: http://www.opensource.apple.com/source/kext_tools/kext_tools-19.2/kextd_main.c?txt
// apple HAS SUGGESTED them too: http://lists.apple.com/archives/darwin-development/2002/Sep/msg00250.html
// gstreamer uses them too: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/sys/osxvideo/osxvideosink.m
func ensureMainThread() {
// TODO set to nil like the apple code?
C._CFRunLoopSetCurrent(C.CFRunLoopGetMain())
// TODO is this part necessary?
C._CFMainPThread = C.pthread_self()
}

View File

@ -8,7 +8,3 @@ package ui
// #cgo LDFLAGS: ${SRCDIR}/libui_linux_386.a -lm -ldl
// #cgo pkg-config: gtk+-3.0
import "C"
func ensureMainThread() {
// do nothing; GTK+ doesn't care which thread we're on so long as we don't change it after starting
}

View File

@ -8,7 +8,3 @@ package ui
// #cgo LDFLAGS: ${SRCDIR}/libui_linux_amd64.a -lm -ldl
// #cgo pkg-config: gtk+-3.0
import "C"
func ensureMainThread() {
// do nothing; GTK+ doesn't care which thread we're on so long as we don't change it after starting
}

View File

@ -6,7 +6,3 @@ package ui
// /* note the order; also note the lack of uuid */
// #cgo LDFLAGS: -luser32 -lkernel32 -lusp10 -lgdi32 -lcomctl32 -luxtheme -lmsimg32 -lcomdlg32 -ld2d1 -ldwrite -lole32 -loleaut32 -loleacc -static -static-libgcc -static-libstdc++
import "C"
func ensureMainThread() {
// do nothing; Windows doesn't care which thread we're on so long as we don't change it after starting
}

View File

@ -6,7 +6,3 @@ package ui
// /* note the order; also note the lack of uuid */
// #cgo LDFLAGS: -luser32 -lkernel32 -lusp10 -lgdi32 -lcomctl32 -luxtheme -lmsimg32 -lcomdlg32 -ld2d1 -ldwrite -lole32 -loleaut32 -loleacc -static -static-libgcc -static-libstdc++
import "C"
func ensureMainThread() {
// do nothing; Windows doesn't care which thread we're on so long as we don't change it after starting
}

23
main.go
View File

@ -24,6 +24,13 @@ import (
// }
import "C"
// make sure main() runs on the first thread created by the OS
// if main() calls Main(), things will just work on macOS, where the first thread created by the OS is the only thread allowed to be the main GUI thread
// we might as well lock the OS thread for the other platforms here too (though on those it doesn't matter *which* thread we lock to)
func init() {
runtime.LockOSThread()
}
// Main initializes package ui, runs f to set up the program,
// and executes the GUI main loop. f should set up the program's
// initial state: open the main window, create controls, and set up
@ -32,29 +39,19 @@ import "C"
// nil. If package ui fails to initialize, Main returns an appropriate
// error.
func Main(f func()) error {
errchan := make(chan error)
go start(errchan, f)
return <-errchan
}
func start(errchan chan error, f func()) {
runtime.LockOSThread()
ensureMainThread()
// TODO HEAP SAFETY
opts := C.uiInitOptions{}
estr := C.uiInit(&opts)
if estr != nil {
errchan <- errors.New(C.GoString(estr))
err := errors.New(C.GoString(estr))
C.uiFreeInitError(estr)
return
return err
}
// set up OnShouldQuit()
C.realOnShouldQuit()
QueueMain(f)
C.uiMain()
errchan <- nil
return nil
}
// Quit queues a return from Main. It does not exit the program.