Skip to content

Commit b2a86a1

Browse files
Martin GreenwaldAlexVulaj
Martin Greenwald
authored andcommitted
Do not timeout when WriteControl deadline is zero
A zero value for the Conn.WriteControl deadline specifies no timeout, but the feature was implemented as a very long timeout (1000 hours). This PR updates the code to use no timeout when the deadline is zero. See the discussion in #895 for more details.
1 parent 695e909 commit b2a86a1

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

conn.go

+13-12
Original file line numberDiff line numberDiff line change
@@ -438,23 +438,24 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er
438438
maskBytes(key, 0, buf[6:])
439439
}
440440

441-
d := 1000 * time.Hour
442-
if !deadline.IsZero() {
443-
d = time.Until(deadline)
441+
if deadline.IsZero() {
442+
// No timeout for zero time.
443+
<-c.mu
444+
} else {
445+
d := time.Until(deadline)
444446
if d < 0 {
445447
return errWriteTimeout
446448
}
447-
}
448-
449-
select {
450-
case <-c.mu:
451-
default:
452-
timer := time.NewTimer(d)
453449
select {
454450
case <-c.mu:
455-
timer.Stop()
456-
case <-timer.C:
457-
return errWriteTimeout
451+
default:
452+
timer := time.NewTimer(d)
453+
select {
454+
case <-c.mu:
455+
timer.Stop()
456+
case <-timer.C:
457+
return errWriteTimeout
458+
}
458459
}
459460
}
460461

conn_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,22 @@ func TestFraming(t *testing.T) {
148148
}
149149
}
150150

151+
func TestWriteControlDeadline(t *testing.T) {
152+
t.Parallel()
153+
message := []byte("hello")
154+
var connBuf bytes.Buffer
155+
c := newTestConn(nil, &connBuf, true)
156+
if err := c.WriteControl(PongMessage, message, time.Time{}); err != nil {
157+
t.Errorf("WriteControl(..., zero deadline) = %v, want nil", err)
158+
}
159+
if err := c.WriteControl(PongMessage, message, time.Now().Add(time.Second)); err != nil {
160+
t.Errorf("WriteControl(..., future deadline) = %v, want nil", err)
161+
}
162+
if err := c.WriteControl(PongMessage, message, time.Now().Add(-time.Second)); err == nil {
163+
t.Errorf("WriteControl(..., past deadline) = nil, want timeout error")
164+
}
165+
}
166+
151167
func TestConcurrencyWriteControl(t *testing.T) {
152168
const message = "this is a ping/pong messsage"
153169
loop := 10

0 commit comments

Comments
 (0)