LockOSThread

Jeremy Jackins edited this page Jan 27, 2015 · 4 revisions
Clone this wiki locally

Introduction

Some libraries, especially graphical frameworks/libraries like Cocoa, OpenGL, libSDL all require it's called from the main OS thread or called from the same OS thread due to its use of thread local data structures. Go's runtime provides LockOSThread() function for this, but it's notoriously difficult to use correctly.

Solutions

Russ Cox presented a good solution for this problem in this thread.

package sdl

// Arrange that main.main runs on main thread.
func init() {
    runtime.LockOSThread()
}

// Main runs the main SDL service loop.
// The binary's main.main must call sdl.Main() to run this loop.
// Main does not return. If the binary needs to do other work, it
// must do it in separate goroutines.
func Main() {
    for f := range mainfunc {
        f()
    }
}

// queue of work to run in main thread.
var mainfunc = make(chan func())

// do runs f on the main thread.
func do(f func()) {
    done := make(chan bool, 1)
    mainfunc <- func() {
        f()
        done <- true
    }
    <-done
}

And then other functions you write in package sdl can be like

func Beep() {
    do(func() {
        // whatever must run in main thread
    })
}