Skip to content

Commit 3a2c79b

Browse files
committed
go: simplify the Write timeout handling
Previously we had a complicated set of channels and a condition variable, and the condition variable Wait() was in a goroutine. Instead the Wait() is now in the main goroutine and an optional timeout is in an optional goroutine. Signed-off-by: David Scott <[email protected]>
1 parent 43190e9 commit 3a2c79b

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

go/pkg/libproxy/multiplexed.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -160,28 +160,28 @@ func (c *channel) Write(p []byte) (int, error) {
160160
continue
161161
}
162162

163-
// Wait for the write window to be increased (or a timeout)
164-
done := make(chan struct{})
165-
timeout := make(chan time.Time)
163+
// If the client has set a deadline then create a timer:
164+
var (
165+
timer *time.Timer
166+
timeOut bool
167+
)
166168
if !c.writeDeadline.IsZero() {
167-
go func() {
168-
time.Sleep(time.Until(c.writeDeadline))
169-
close(timeout)
170-
}()
169+
timer = time.AfterFunc(time.Until(c.writeDeadline), func() {
170+
c.m.Lock()
171+
defer c.m.Unlock()
172+
timeOut = true
173+
c.c.Broadcast()
174+
})
171175
}
172-
go func() {
173-
c.c.Wait()
174-
close(done)
175-
}()
176-
select {
177-
case <-timeout:
178-
// clean up the goroutine
179-
c.c.Broadcast()
180-
<-done
176+
177+
// Wait for the write window to be increased or a timeout
178+
c.c.Wait()
179+
180+
if timer != nil {
181+
timer.Stop()
182+
}
183+
if timeOut {
181184
return written, &errTimeout{}
182-
case <-done:
183-
// The timeout will still fire in the background
184-
continue
185185
}
186186
}
187187
}

0 commit comments

Comments
 (0)