crypto/tls: don't block in Conn.Close if Writes are in-flight
Conn.Close sends an encrypted "close notify" to signal secure EOF. But writing that involves acquiring mutexes (handshake mutex + the c.out mutex) and writing to the network. But if the reason we're calling Conn.Close is because the network is already being problematic, then Close might block, waiting for one of those mutexes. Instead of blocking, and instead of introducing new API (at least for now), distinguish between a normal Close (one that sends a secure EOF) and a resource-releasing destructor-style Close based on whether there are existing Write calls in-flight. Because io.Writer and io.Closer aren't defined with respect to concurrent usage, a Close with active Writes is already undefined, and should only be used during teardown after failures (e.g. deadlines or cancelations by HTTP users). A normal user will do a Write then serially do a Close, and things are unchanged for that case. This should fix the leaked goroutines and hung net/http.Transport requests when there are network errors while making TLS requests. Change-Id: If3f8c69d6fdcebf8c70227f41ad042ccc3f20ac9 Reviewed-on: https://go-review.googlesource.com/18572Reviewed-by: Adam Langley <agl@golang.org> Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Showing
Please register or sign in to comment