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:
parent
6c3bda44d3
commit
dc108a5d4d
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
23
main.go
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue