Skip to content

Commit

Permalink
go: simplify the Write timeout handling
Browse files Browse the repository at this point in the history
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 <dave@recoil.org>
  • Loading branch information
djs55 committed Feb 17, 2023
1 parent 43190e9 commit 3a2c79b
Showing 1 changed file with 19 additions and 19 deletions.
38 changes: 19 additions & 19 deletions go/pkg/libproxy/multiplexed.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,28 +160,28 @@ func (c *channel) Write(p []byte) (int, error) {
continue
}

// Wait for the write window to be increased (or a timeout)
done := make(chan struct{})
timeout := make(chan time.Time)
// If the client has set a deadline then create a timer:
var (
timer *time.Timer
timeOut bool
)
if !c.writeDeadline.IsZero() {
go func() {
time.Sleep(time.Until(c.writeDeadline))
close(timeout)
}()
timer = time.AfterFunc(time.Until(c.writeDeadline), func() {
c.m.Lock()
defer c.m.Unlock()
timeOut = true
c.c.Broadcast()
})
}
go func() {
c.c.Wait()
close(done)
}()
select {
case <-timeout:
// clean up the goroutine
c.c.Broadcast()
<-done

// Wait for the write window to be increased or a timeout
c.c.Wait()

if timer != nil {
timer.Stop()
}
if timeOut {
return written, &errTimeout{}
case <-done:
// The timeout will still fire in the background
continue
}
}
}
Expand Down

0 comments on commit 3a2c79b

Please sign in to comment.