blob: aad4e7d1c6147af463e3d75d39181f2ce1a995f0 [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Introduction
2
3Some libraries, especially graphical frameworks/libraries like Cocoa, OpenGL, libSDL all require it's
4called from the main OS thread or called from the same OS thread due to its use of thread local
5data structures. Go's runtime provides ` LockOSThread() ` function for this, but it's notoriously difficult
6to use correctly.
7
8# Solutions
9
10Russ Cox presented a good solution for this problem in this [thread](https://groups.google.com/d/msg/golang-nuts/IiWZ2hUuLDA/SNKYYZBelsYJ).
11
Dmitri Shuralyov47f767a2015-01-04 21:07:59 -080012```Go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110013package sdl
14
15// Arrange that main.main runs on main thread.
16func init() {
Dave Day0d6986a2014-12-10 15:02:18 +110017 runtime.LockOSThread()
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110018}
19
20// Main runs the main SDL service loop.
21// The binary's main.main must call sdl.Main() to run this loop.
22// Main does not return. If the binary needs to do other work, it
23// must do it in separate goroutines.
24func Main() {
Jeremy Jackins18049022015-01-27 22:24:43 +090025 for f := range mainfunc {
Dave Day0d6986a2014-12-10 15:02:18 +110026 f()
27 }
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110028}
29
30// queue of work to run in main thread.
31var mainfunc = make(chan func())
32
33// do runs f on the main thread.
34func do(f func()) {
Dave Day0d6986a2014-12-10 15:02:18 +110035 done := make(chan bool, 1)
36 mainfunc <- func() {
37 f()
38 done <- true
39 }
40 <-done
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110041}
42```
43
44And then other functions you write in package sdl can be like
Dmitri Shuralyov47f767a2015-01-04 21:07:59 -080045
46```Go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110047func Beep() {
Dave Day0d6986a2014-12-10 15:02:18 +110048 do(func() {
49 // whatever must run in main thread
50 })
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110051}
52```