shiny/driver/gldriver: initialize glctx fields earlier.

A *windowImpl's glctx and worker fields should really be set on
construction (and never modified afterwards), as fields in the
&windowImpl{ etc } literal during screenImpl.NewWindow. However, the
initialization values are platform specific, so they are initialized in
a separate function call.

Until now, that function call was showWindow, as it is called
conveniently soon after newWindow returns. showWindow's primary purpose
is mostly unrelated: to show the freshly created window on the screen.

Soon isn't soon enough, though. The (implemented in C) message pump
happens in another thread, which can trigger callbacks like onConfigure,
which (racily) reads the w.glctx field with lines like:

w.lifecycler.SendEvent(w, w.glctx)

This commit fixes the race, originally reported at
https://github.com/golang/exp/pull/3

Change-Id: I69d50b037ec4c4f021ca60f570f86723c17d7bb7
Reviewed-on: https://go-review.googlesource.com/34873
Reviewed-by: David Crawshaw <crawshaw@golang.org>
diff --git a/shiny/driver/gldriver/cocoa.go b/shiny/driver/gldriver/cocoa.go
index 3f82485..b089c64 100644
--- a/shiny/driver/gldriver/cocoa.go
+++ b/shiny/driver/gldriver/cocoa.go
@@ -65,11 +65,11 @@
 	return uintptr(C.doNewWindow(C.int(width), C.int(height))), nil
 }
 
-func showWindow(w *windowImpl) {
-	w.glctxMu.Lock()
+func initWindow(w *windowImpl) {
 	w.glctx, w.worker = gl.NewContext()
-	w.glctxMu.Unlock()
+}
 
+func showWindow(w *windowImpl) {
 	C.doShowWindow(C.uintptr_t(w.id))
 }
 
diff --git a/shiny/driver/gldriver/other.go b/shiny/driver/gldriver/other.go
index b0fcccc..d3c49b8 100644
--- a/shiny/driver/gldriver/other.go
+++ b/shiny/driver/gldriver/other.go
@@ -17,6 +17,7 @@
 
 func newWindow(opts *screen.NewWindowOptions) (uintptr, error) { return 0, nil }
 
+func initWindow(id *windowImpl) {}
 func showWindow(id *windowImpl) {}
 func closeWindow(id uintptr)    {}
 func drawLoop(w *windowImpl)    {}
diff --git a/shiny/driver/gldriver/screen.go b/shiny/driver/gldriver/screen.go
index f9ad487..3100ebc 100644
--- a/shiny/driver/gldriver/screen.go
+++ b/shiny/driver/gldriver/screen.go
@@ -133,6 +133,7 @@
 		publishDone: make(chan screen.PublishResult),
 		drawDone:    make(chan struct{}),
 	}
+	initWindow(w)
 
 	s.mu.Lock()
 	s.windows[id] = w
diff --git a/shiny/driver/gldriver/win32.go b/shiny/driver/gldriver/win32.go
index 7e5438e..9e73f71 100755
--- a/shiny/driver/gldriver/win32.go
+++ b/shiny/driver/gldriver/win32.go
@@ -72,11 +72,11 @@
 	return uintptr(w), nil
 }
 
-func showWindow(w *windowImpl) {
-	w.glctxMu.Lock()
+func initWindow(w *windowImpl) {
 	w.glctx, w.worker = gl.NewContext()
-	w.glctxMu.Unlock()
+}
 
+func showWindow(w *windowImpl) {
 	// Show makes an initial call to sizeEvent (via win32.SizeEvent), where
 	// we setup the EGL surface and GL context.
 	win32.Show(syscall.Handle(w.id))
diff --git a/shiny/driver/gldriver/x11.go b/shiny/driver/gldriver/x11.go
index ea8f07c..03f68e6 100644
--- a/shiny/driver/gldriver/x11.go
+++ b/shiny/driver/gldriver/x11.go
@@ -60,6 +60,10 @@
 	return <-retc, nil
 }
 
+func initWindow(w *windowImpl) {
+	w.glctx, w.worker = glctx, worker
+}
+
 func showWindow(w *windowImpl) {
 	retc := make(chan uintptr)
 	uic <- uiClosure{
@@ -69,9 +73,6 @@
 		retc: retc,
 	}
 	w.ctx = <-retc
-	w.glctxMu.Lock()
-	w.glctx, w.worker = glctx, worker
-	w.glctxMu.Unlock()
 	go drawLoop(w)
 }