Replace wantWriteFrameCh with a method.

Also add more notes about which goroutines things should run on,
and add another check which found a bug (potential deadlock) in Ping processing.
diff --git a/gotrack.go b/gotrack.go
index b5dde40..1f55905 100644
--- a/gotrack.go
+++ b/gotrack.go
@@ -36,6 +36,15 @@
 	}
 }
 
+func (g goroutineLock) checkNotOn() {
+	if !DebugGoroutines {
+		return
+	}
+	if curGoroutineID() == uint64(g) {
+		panic("running on the wrong goroutine")
+	}
+}
+
 var goroutineSpace = []byte("goroutine ")
 
 func curGoroutineID() uint64 {
diff --git a/server.go b/server.go
index d8ea1eb..51f8035 100644
--- a/server.go
+++ b/server.go
@@ -31,6 +31,8 @@
 	firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
 )
 
+// TODO: automatic 100-continue
+
 // TODO: finish GOAWAY support. Consider each incoming frame type and
 // whether it should be ignored during a shutdown race.
 
@@ -398,6 +400,13 @@
 	}
 }
 
+// should be called from non-serve() goroutines, otherwise the ends may deadlock
+// the serve loop. (it's only buffered a little bit).
+func (sc *serverConn) writeFrame(wm frameWriteMsg) {
+	sc.serveG.checkNotOn() // note the "NOT"
+	sc.wantWriteFrameCh <- wm
+}
+
 func (sc *serverConn) enqueueFrameWrite(wm frameWriteMsg) {
 	sc.serveG.check()
 	// Fast path for common case:
@@ -413,7 +422,7 @@
 	sc.serveG.check()
 	// Fast path for common case:
 	if !sc.writingFrame {
-		sc.wantWriteFrameCh <- frameWriteMsg{write: (*serverConn).writeSettingsAck}
+		sc.writeFrameCh <- frameWriteMsg{write: (*serverConn).writeSettingsAck}
 		return
 	}
 	sc.needToSendSettingsAck = true
@@ -572,10 +581,10 @@
 		// PROTOCOL_ERROR."
 		return ConnectionError(ErrCodeProtocol)
 	}
-	sc.wantWriteFrameCh <- frameWriteMsg{
+	sc.enqueueFrameWrite(frameWriteMsg{
 		write: (*serverConn).writePingAck,
 		v:     f,
-	}
+	})
 	return nil
 }
 
@@ -904,6 +913,7 @@
 // called from handler goroutines.
 // h may be nil.
 func (sc *serverConn) writeHeaders(req headerWriteReq) {
+	sc.serveG.checkNotOn()
 	var errc chan error
 	if req.h != nil {
 		// If there's a header map (which we don't own), so we have to block on
@@ -912,12 +922,12 @@
 		// mutates it.
 		errc = make(chan error, 1)
 	}
-	sc.wantWriteFrameCh <- frameWriteMsg{
+	sc.writeFrame(frameWriteMsg{
 		write:    (*serverConn).writeHeadersFrame,
 		v:        req,
 		streamID: req.streamID,
 		done:     errc,
-	}
+	})
 	if errc != nil {
 		<-errc
 	}
@@ -974,19 +984,19 @@
 func (sc *serverConn) sendWindowUpdate(streamID uint32, n int) {
 	const maxUint32 = 2147483647
 	for n >= maxUint32 {
-		sc.wantWriteFrameCh <- frameWriteMsg{
+		sc.writeFrame(frameWriteMsg{
 			write:    (*serverConn).sendWindowUpdateInLoop,
 			v:        windowUpdateReq{streamID, maxUint32},
 			streamID: streamID,
-		}
+		})
 		n -= maxUint32
 	}
 	if n > 0 {
-		sc.wantWriteFrameCh <- frameWriteMsg{
+		sc.writeFrame(frameWriteMsg{
 			write:    (*serverConn).sendWindowUpdateInLoop,
 			v:        windowUpdateReq{streamID, uint32(n)},
 			streamID: streamID,
-		}
+		})
 	}
 }
 
@@ -1123,13 +1133,13 @@
 	rws.curChunkIsFinal = rws.handlerDone
 
 	// TODO: await flow control tokens for both stream and conn
-	rws.sc.wantWriteFrameCh <- frameWriteMsg{
+	rws.sc.writeFrame(frameWriteMsg{
 		cost:     uint32(len(p)),
 		streamID: rws.streamID,
 		write:    (*serverConn).writeDataFrame,
 		done:     rws.chunkWrittenCh,
 		v:        rws, // writeDataInLoop uses only rws.curChunk and rws.curChunkIsFinal
-	}
+	})
 	err = <-rws.chunkWrittenCh // block until it's written
 	return len(p), err
 }