@@ -51,9 +51,8 @@ type Conn struct {
51
51
br * bufio.Reader
52
52
bw * bufio.Writer
53
53
54
- readTimeout chan context.Context
55
- writeTimeout chan context.Context
56
- timeoutLoopDone chan struct {}
54
+ readTimeoutStop atomic.Pointer [func () bool ]
55
+ writeTimeoutStop atomic.Pointer [func () bool ]
57
56
58
57
// Read state.
59
58
readMu * mu
@@ -113,10 +112,6 @@ func newConn(cfg connConfig) *Conn {
113
112
br : cfg .br ,
114
113
bw : cfg .bw ,
115
114
116
- readTimeout : make (chan context.Context ),
117
- writeTimeout : make (chan context.Context ),
118
- timeoutLoopDone : make (chan struct {}),
119
-
120
115
closed : make (chan struct {}),
121
116
activePings : make (map [string ]chan <- struct {}),
122
117
onPingReceived : cfg .onPingReceived ,
@@ -144,8 +139,6 @@ func newConn(cfg connConfig) *Conn {
144
139
c .close ()
145
140
})
146
141
147
- go c .timeoutLoop ()
148
-
149
142
return c
150
143
}
151
144
@@ -175,27 +168,34 @@ func (c *Conn) close() error {
175
168
return err
176
169
}
177
170
178
- func (c * Conn ) timeoutLoop () {
179
- defer close (c .timeoutLoopDone )
171
+ func (c * Conn ) setupWriteTimeout (ctx context.Context ) {
172
+ stop := context .AfterFunc (ctx , func () {
173
+ c .clearWriteTimeout ()
174
+ c .close ()
175
+ })
176
+ swapTimeoutStop (& c .writeTimeoutStop , & stop )
177
+ }
180
178
181
- readCtx := context .Background ()
182
- writeCtx := context .Background ()
179
+ func (c * Conn ) clearWriteTimeout () {
180
+ swapTimeoutStop (& c .writeTimeoutStop , nil )
181
+ }
183
182
184
- for {
185
- select {
186
- case <- c .closed :
187
- return
188
-
189
- case writeCtx = <- c .writeTimeout :
190
- case readCtx = <- c .readTimeout :
191
-
192
- case <- readCtx .Done ():
193
- c .close ()
194
- return
195
- case <- writeCtx .Done ():
196
- c .close ()
197
- return
198
- }
183
+ func (c * Conn ) setupReadTimeout (ctx context.Context ) {
184
+ stop := context .AfterFunc (ctx , func () {
185
+ c .clearReadTimeout ()
186
+ c .close ()
187
+ })
188
+ swapTimeoutStop (& c .readTimeoutStop , & stop )
189
+ }
190
+
191
+ func (c * Conn ) clearReadTimeout () {
192
+ swapTimeoutStop (& c .readTimeoutStop , nil )
193
+ }
194
+
195
+ func swapTimeoutStop (p * atomic.Pointer [func () bool ], newStop * func () bool ) {
196
+ oldStop := p .Swap (newStop )
197
+ if oldStop != nil {
198
+ (* oldStop )()
199
199
}
200
200
}
201
201
0 commit comments