mirror of https://github.com/gorilla/websocket.git
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.
This commit is contained in:
parent
695e9095ce
commit
b2a86a1744
25
conn.go
25
conn.go
|
@ -438,23 +438,24 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er
|
||||||
maskBytes(key, 0, buf[6:])
|
maskBytes(key, 0, buf[6:])
|
||||||
}
|
}
|
||||||
|
|
||||||
d := 1000 * time.Hour
|
if deadline.IsZero() {
|
||||||
if !deadline.IsZero() {
|
// No timeout for zero time.
|
||||||
d = time.Until(deadline)
|
<-c.mu
|
||||||
|
} else {
|
||||||
|
d := time.Until(deadline)
|
||||||
if d < 0 {
|
if d < 0 {
|
||||||
return errWriteTimeout
|
return errWriteTimeout
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-c.mu:
|
|
||||||
default:
|
|
||||||
timer := time.NewTimer(d)
|
|
||||||
select {
|
select {
|
||||||
case <-c.mu:
|
case <-c.mu:
|
||||||
timer.Stop()
|
default:
|
||||||
case <-timer.C:
|
timer := time.NewTimer(d)
|
||||||
return errWriteTimeout
|
select {
|
||||||
|
case <-c.mu:
|
||||||
|
timer.Stop()
|
||||||
|
case <-timer.C:
|
||||||
|
return errWriteTimeout
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
conn_test.go
16
conn_test.go
|
@ -148,6 +148,22 @@ func TestFraming(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriteControlDeadline(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
message := []byte("hello")
|
||||||
|
var connBuf bytes.Buffer
|
||||||
|
c := newTestConn(nil, &connBuf, true)
|
||||||
|
if err := c.WriteControl(PongMessage, message, time.Time{}); err != nil {
|
||||||
|
t.Errorf("WriteControl(..., zero deadline) = %v, want nil", err)
|
||||||
|
}
|
||||||
|
if err := c.WriteControl(PongMessage, message, time.Now().Add(time.Second)); err != nil {
|
||||||
|
t.Errorf("WriteControl(..., future deadline) = %v, want nil", err)
|
||||||
|
}
|
||||||
|
if err := c.WriteControl(PongMessage, message, time.Now().Add(-time.Second)); err == nil {
|
||||||
|
t.Errorf("WriteControl(..., past deadline) = nil, want timeout error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestConcurrencyWriteControl(t *testing.T) {
|
func TestConcurrencyWriteControl(t *testing.T) {
|
||||||
const message = "this is a ping/pong messsage"
|
const message = "this is a ping/pong messsage"
|
||||||
loop := 10
|
loop := 10
|
||||||
|
|
Loading…
Reference in New Issue