Please answer these questions before submitting your issue. Thanks!
What did you do?
I write a tcp server using "crypto/tls", it listen on a port. just like this:
for {
conn, err := netListen.Accept()
if nil != err {
continue
}
go handleConnection(conn)
}
In handleConnection, a separate go routine recvFromTcp is created for TCP reading operation, and timeout judgement is made in the main goroutine. When 30 seconds can't get the TCP client's message, it will close the connection.
I use telnet to connect the server, and after 30 seconds the server-side determines the timeout, and the recvFromTcp group is stuck in Read when the Conn's Close () is called. Two go routine can't quit
What did you expect to see?
tcp server using "crypto/tls" , listen on a port ,when I run telnet on wondows, Server-side timeout judgment, one goroutine call Close() of net.Conn, conn.Read in another goroutine will return err immediately。
What did you see instead?
when one goroutine call Close() of net.Conn,conn.Read in another goroutine is blocked in Read。
System details
call Close in one goroutine:
# 0x43fe1c sync.runtime_SemacquireMutex+0x3c /usr/local/go/src/runtime/sema.go:71
# 0x472a7d sync.(*Mutex).Lock+0xed /usr/local/go/src/sync/mutex.go:134
# 0x60bc5b crypto/tls.(*Conn).Close+0x6b /usr/local/go/src/crypto/tls/conn.go:1208
# 0x7e4df9 main.handleConnection.func1+0x59
# 0x7d981d main.handleConnection+0x81d
another goroutine is blocked in Read of net.Conn:
# 0x429456 internal/poll.runtime_pollWait+0x56 /usr/local/go/src/runtime/netpoll.go:173
# 0x49253d internal/poll.(*pollDesc).wait+0xad /usr/local/go/src/internal/poll/fd_poll_runtime.go:85
# 0x4925bc internal/poll.(*pollDesc).waitRead+0x3c /usr/local/go/src/internal/poll/fd_poll_runtime.go:90
# 0x493359 internal/poll.(*FD).Read+0x189 /usr/local/go/src/internal/poll/fd_unix.go:125
# 0x5afc51 net.(*netFD).Read+0x51 /usr/local/go/src/net/fd_unix.go:202
# 0x5c21ec net.(*conn).Read+0x6c /usr/local/go/src/net/net.go:176
# 0x6077b4 crypto/tls.(*block).readFromUntil+0x94 /usr/local/go/src/crypto/tls/conn.go:488
# 0x607d1f crypto/tls.(*Conn).readRecord+0xdf /usr/local/go/src/crypto/tls/conn.go:590
# 0x60a68c crypto/tls.(*Conn).readHandshake+0x8c /usr/local/go/src/crypto/tls/conn.go:943
# 0x61a31d crypto/tls.(*serverHandshakeState).readClientHello+0x4d /usr/local/go/src/crypto/tls/handshake_server.go:116
# 0x619e5d crypto/tls.(*Conn).serverHandshake+0xad /usr/local/go/src/crypto/tls/handshake_server.go:48
# 0x60c1ee crypto/tls.(*Conn).Handshake+0x27e /usr/local/go/src/crypto/tls/conn.go:1309
# 0x60b7b2 crypto/tls.(*Conn).Read+0x52 /usr/local/go/src/crypto/tls/conn.go:1117
# 0x7d7e0c main.recvFromTcp+0x48c
go version go1.9 linux/amd64
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/teld/gocode:/home/teld/gocode/fes/simctrl:/home/teld/gocode/fes/setgetctrl:/home/teld/gocode/fes/prot_tcp_protobuf:/home/teld/gocode/fes/prot_tcp_protobuf_monitor"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build436166746=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOROOT/bin/go version: go version go1.9 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.9
uname -sr: Linux 3.10.0-514.26.2.el7.x86_64
/lib64/libc.so.6: GNU C Library (GNU libc) stable release version 2.17, by Roland McGrath et al.
gdb --version: GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7
Please answer these questions before submitting your issue. Thanks!
What did you do?
I write a tcp server using "crypto/tls", it listen on a port. just like this:
for {
conn, err := netListen.Accept()
if nil != err {
continue
}
go handleConnection(conn)
}
In handleConnection, a separate go routine recvFromTcp is created for TCP reading operation, and timeout judgement is made in the main goroutine. When 30 seconds can't get the TCP client's message, it will close the connection.
I use telnet to connect the server, and after 30 seconds the server-side determines the timeout, and the recvFromTcp group is stuck in Read when the Conn's Close () is called. Two go routine can't quit
What did you expect to see?
tcp server using "crypto/tls" , listen on a port ,when I run telnet on wondows, Server-side timeout judgment, one goroutine call Close() of net.Conn, conn.Read in another goroutine will return err immediately。
What did you see instead?
when one goroutine call Close() of net.Conn,conn.Read in another goroutine is blocked in Read。
System details
call Close in one goroutine:
another goroutine is blocked in Read of net.Conn: