Skip to content

Commit 6770421

Browse files
committed
Fix goroutine leak from deadlock when closing
1 parent 6b38ebb commit 6770421

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

conn_test.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ func TestConn(t *testing.T) {
348348
}()
349349
defer cancel()
350350

351-
c1.SetReadLimit(131072)
351+
c1.SetReadLimit(1 << 30)
352352

353353
exp := xrand.String(xrand.Int(131072))
354354

@@ -401,8 +401,6 @@ func TestConn(t *testing.T) {
401401
}()
402402
defer cancel()
403403

404-
c1.SetReadLimit(131072)
405-
406404
exp := ptypes.DurationProto(100)
407405
err = wspb.Write(ctx, c1, exp)
408406
if err != nil {

read.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ func (c *Conn) CloseRead(ctx context.Context) context.Context {
6969
//
7070
// When the limit is hit, the connection will be closed with StatusMessageTooBig.
7171
func (c *Conn) SetReadLimit(n int64) {
72-
c.msgReader.limitReader.limit.Store(n)
72+
// We add read one more byte than the limit in case
73+
// there is a fin frame that needs to be read.
74+
c.msgReader.limitReader.limit.Store(n + 1)
7375
}
7476

7577
const defaultReadLimit = 32768
@@ -80,7 +82,7 @@ func newMsgReader(c *Conn) *msgReader {
8082
fin: true,
8183
}
8284

83-
mr.limitReader = newLimitReader(c, readerFunc(mr.read), defaultReadLimit)
85+
mr.limitReader = newLimitReader(c, readerFunc(mr.read), defaultReadLimit+1)
8486
return mr
8587
}
8688

write.go

+18-4
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error {
5050
type msgWriter struct {
5151
c *Conn
5252

53-
mu *mu
53+
mu *mu
54+
activeMu *mu
5455

5556
ctx context.Context
5657
opcode opcode
@@ -63,8 +64,9 @@ type msgWriter struct {
6364

6465
func newMsgWriter(c *Conn) *msgWriter {
6566
mw := &msgWriter{
66-
c: c,
67-
mu: newMu(c),
67+
c: c,
68+
mu: newMu(c),
69+
activeMu: newMu(c),
6870
}
6971
return mw
7072
}
@@ -147,6 +149,12 @@ func (mw *msgWriter) returnFlateWriter() {
147149
func (mw *msgWriter) Write(p []byte) (_ int, err error) {
148150
defer errd.Wrap(&err, "failed to write")
149151

152+
err = mw.activeMu.Lock(mw.ctx)
153+
if err != nil {
154+
return 0, err
155+
}
156+
defer mw.activeMu.Unlock()
157+
150158
if mw.closed {
151159
return 0, xerrors.New("cannot use closed writer")
152160
}
@@ -173,6 +181,12 @@ func (mw *msgWriter) write(p []byte) (int, error) {
173181
func (mw *msgWriter) Close() (err error) {
174182
defer errd.Wrap(&err, "failed to close writer")
175183

184+
err = mw.activeMu.Lock(mw.ctx)
185+
if err != nil {
186+
return err
187+
}
188+
defer mw.activeMu.Unlock()
189+
176190
if mw.closed {
177191
return xerrors.New("cannot use closed writer")
178192
}
@@ -201,7 +215,7 @@ func (mw *msgWriter) Close() (err error) {
201215
}
202216

203217
func (mw *msgWriter) close() {
204-
mw.mu.Lock(context.Background())
218+
mw.activeMu.Lock(context.Background())
205219
mw.returnFlateWriter()
206220
}
207221

0 commit comments

Comments
 (0)