http2: fix server race
This changes makes sure we never write to *writeData in the ServeHTTP goroutine until the serve goroutine is done with it. Also, it makes sure we don't transition the stream to the closed state on the final DATA frame concurrently with the write. To fix both, the writeFrameAsync goroutine no longer replies directly back to the ServeHTTP goroutine with the write result. It's now passed to the serve goroutine instead, which looks at the frameWriteMsg to decide how to advance the state machine, then signals the ServeHTTP goroutine with the result, and then advances the state machine. Because advancing the state machine could transition it to closed, which the ServeHTTP goroutine might also be selecting on, make the ServeHTTP goroutine prefer its frameWriteMsg response channel for errors over the stream closure in its select. Various code simplifications and robustness in the process. Tests now pass reliably even with high -count values, -race on/off, etc. I've been unable to make h2load be unhappy now either. Thanks to Tatsuhiro Tsujikawa (Github user @tatsuhiro-t) for the bug report and debugging clues. Fixes golang/go#12998 Change-Id: I441c4c9ca928eaba89fd4728d213019606edd899 Reviewed-on: https://go-review.googlesource.com/16063Reviewed-by: Andrew Gerrand <adg@golang.org>
Showing
Please
register
or
sign in
to comment