]> Cypherpunks repositories - gostls13.git/commit
crypto/tls: don't block in Conn.Close if Writes are in-flight
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 12 Jan 2016 21:15:51 +0000 (21:15 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 13 Jan 2016 04:49:19 +0000 (04:49 +0000)
commit4ffba768555a14fe2730af27a4508ccd21eef65b
tree63db3c8a2943c7a7608463ac57c9502429c6ef2c
parente779bfa5d212014b65948abe559795ef1e6d056c
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/18572
Reviewed-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>
src/crypto/tls/conn.go
src/crypto/tls/tls_test.go