Skip to content

Commit ad3f0c2

Browse files
committed
abolish an extra goroutine
1 parent 1253b77 commit ad3f0c2

File tree

4 files changed

+48
-39
lines changed

4 files changed

+48
-39
lines changed

close.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,6 @@ func (c *Conn) waitGoroutines() error {
232232
t := time.NewTimer(time.Second * 15)
233233
defer t.Stop()
234234

235-
select {
236-
case <-c.timeoutLoopDone:
237-
case <-t.C:
238-
return errors.New("failed to wait for timeoutLoop goroutine to exit")
239-
}
240-
241235
c.closeReadMu.Lock()
242236
closeRead := c.closeReadCtx != nil
243237
c.closeReadMu.Unlock()

conn.go

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ type Conn struct {
5252
br *bufio.Reader
5353
bw *bufio.Writer
5454

55-
readTimeout chan context.Context
56-
writeTimeout chan context.Context
57-
timeoutLoopDone chan struct{}
55+
readTimeoutCloser atomic.Value
56+
writeTimeoutCloser atomic.Value
5857

5958
// Read state.
6059
readMu *mu
@@ -104,10 +103,6 @@ func newConn(cfg connConfig) *Conn {
104103
br: cfg.br,
105104
bw: cfg.bw,
106105

107-
readTimeout: make(chan context.Context),
108-
writeTimeout: make(chan context.Context),
109-
timeoutLoopDone: make(chan struct{}),
110-
111106
closed: make(chan struct{}),
112107
activePings: make(map[string]chan<- struct{}),
113108
}
@@ -133,8 +128,6 @@ func newConn(cfg connConfig) *Conn {
133128
c.close()
134129
})
135130

136-
go c.timeoutLoop()
137-
138131
return c
139132
}
140133

@@ -164,26 +157,42 @@ func (c *Conn) close() error {
164157
return err
165158
}
166159

167-
func (c *Conn) timeoutLoop() {
168-
defer close(c.timeoutLoopDone)
160+
func (c *Conn) setupWriteTimeout(ctx context.Context) {
161+
hammerTime := context.AfterFunc(ctx, func() {
162+
c.close()
163+
})
169164

170-
readCtx := context.Background()
171-
writeCtx := context.Background()
165+
if closer := c.writeTimeoutCloser.Swap(hammerTime); closer != nil {
166+
if fn, ok := closer.(func() bool); ok {
167+
fn()
168+
}
169+
}
170+
}
172171

173-
for {
174-
select {
175-
case <-c.closed:
176-
return
177-
178-
case writeCtx = <-c.writeTimeout:
179-
case readCtx = <-c.readTimeout:
180-
181-
case <-readCtx.Done():
182-
c.close()
183-
return
184-
case <-writeCtx.Done():
185-
c.close()
186-
return
172+
func (c *Conn) clearWriteTimeout() {
173+
if closer := c.writeTimeoutCloser.Load(); closer != nil {
174+
if fn, ok := closer.(func() bool); ok {
175+
fn()
176+
}
177+
}
178+
}
179+
180+
func (c *Conn) setupReadTimeout(ctx context.Context) {
181+
hammerTime := context.AfterFunc(ctx, func() {
182+
defer c.close()
183+
})
184+
185+
if closer := c.readTimeoutCloser.Swap(hammerTime); closer != nil {
186+
if fn, ok := closer.(func() bool); ok {
187+
fn()
188+
}
189+
}
190+
}
191+
192+
func (c *Conn) clearReadTimeout() {
193+
if closer := c.readTimeoutCloser.Load(); closer != nil {
194+
if fn, ok := closer.(func() bool); ok {
195+
fn()
187196
}
188197
}
189198
}

read.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ func (c *Conn) readFrameHeader(ctx context.Context) (header, error) {
221221
select {
222222
case <-c.closed:
223223
return header{}, net.ErrClosed
224-
case c.readTimeout <- ctx:
224+
default:
225+
c.setupReadTimeout(ctx)
225226
}
226227

227228
h, err := readFrameHeader(c.br, c.readHeaderBuf[:])
@@ -239,7 +240,8 @@ func (c *Conn) readFrameHeader(ctx context.Context) (header, error) {
239240
select {
240241
case <-c.closed:
241242
return header{}, net.ErrClosed
242-
case c.readTimeout <- context.Background():
243+
default:
244+
c.clearReadTimeout()
243245
}
244246

245247
return h, nil
@@ -249,7 +251,8 @@ func (c *Conn) readFramePayload(ctx context.Context, p []byte) (int, error) {
249251
select {
250252
case <-c.closed:
251253
return 0, net.ErrClosed
252-
case c.readTimeout <- ctx:
254+
default:
255+
c.setupReadTimeout(ctx)
253256
}
254257

255258
n, err := io.ReadFull(c.br, p)
@@ -267,7 +270,8 @@ func (c *Conn) readFramePayload(ctx context.Context, p []byte) (int, error) {
267270
select {
268271
case <-c.closed:
269272
return n, net.ErrClosed
270-
case c.readTimeout <- context.Background():
273+
default:
274+
c.clearReadTimeout()
271275
}
272276

273277
return n, err

write.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ func (c *Conn) writeFrame(ctx context.Context, fin bool, flate bool, opcode opco
252252
select {
253253
case <-c.closed:
254254
return 0, net.ErrClosed
255-
case c.writeTimeout <- ctx:
255+
default:
256+
c.setupWriteTimeout(ctx)
256257
}
257258

258259
defer func() {
@@ -309,7 +310,8 @@ func (c *Conn) writeFrame(ctx context.Context, fin bool, flate bool, opcode opco
309310
return n, nil
310311
}
311312
return n, net.ErrClosed
312-
case c.writeTimeout <- context.Background():
313+
default:
314+
c.clearWriteTimeout()
313315
}
314316

315317
return n, nil

0 commit comments

Comments
 (0)