-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
abolish an extra goroutine #501
base: master
Are you sure you want to change the base?
Changes from all commits
ad3f0c2
7561da2
e226a0f
4b01ac4
ca3439d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,9 +52,8 @@ type Conn struct { | |
br *bufio.Reader | ||
bw *bufio.Writer | ||
|
||
readTimeout chan context.Context | ||
writeTimeout chan context.Context | ||
timeoutLoopDone chan struct{} | ||
readTimeoutCloser atomic.Value | ||
writeTimeoutCloser atomic.Value | ||
|
||
// Read state. | ||
readMu *mu | ||
|
@@ -104,10 +103,6 @@ func newConn(cfg connConfig) *Conn { | |
br: cfg.br, | ||
bw: cfg.bw, | ||
|
||
readTimeout: make(chan context.Context), | ||
writeTimeout: make(chan context.Context), | ||
timeoutLoopDone: make(chan struct{}), | ||
|
||
closed: make(chan struct{}), | ||
activePings: make(map[string]chan<- struct{}), | ||
} | ||
|
@@ -133,8 +128,6 @@ func newConn(cfg connConfig) *Conn { | |
c.close() | ||
}) | ||
|
||
go c.timeoutLoop() | ||
|
||
return c | ||
} | ||
|
||
|
@@ -164,26 +157,42 @@ func (c *Conn) close() error { | |
return err | ||
} | ||
|
||
func (c *Conn) timeoutLoop() { | ||
defer close(c.timeoutLoopDone) | ||
func (c *Conn) setupWriteTimeout(ctx context.Context) { | ||
hammerTime := context.AfterFunc(ctx, func() { | ||
c.close() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it'd be possible for this function to also remove itself from Well, it just needs to call |
||
}) | ||
|
||
readCtx := context.Background() | ||
writeCtx := context.Background() | ||
if closer := c.writeTimeoutCloser.Swap(hammerTime); closer != nil { | ||
if fn, ok := closer.(func() bool); ok { | ||
fn() | ||
} | ||
} | ||
} | ||
|
||
for { | ||
select { | ||
case <-c.closed: | ||
return | ||
|
||
case writeCtx = <-c.writeTimeout: | ||
case readCtx = <-c.readTimeout: | ||
|
||
case <-readCtx.Done(): | ||
c.close() | ||
return | ||
case <-writeCtx.Done(): | ||
c.close() | ||
return | ||
func (c *Conn) clearWriteTimeout() { | ||
if closer := c.writeTimeoutCloser.Load(); closer != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be a |
||
if fn, ok := closer.(func() bool); ok { | ||
fn() | ||
} | ||
} | ||
} | ||
|
||
func (c *Conn) setupReadTimeout(ctx context.Context) { | ||
hammerTime := context.AfterFunc(ctx, func() { | ||
c.close() | ||
}) | ||
|
||
if closer := c.readTimeoutCloser.Swap(hammerTime); closer != nil { | ||
if fn, ok := closer.(func() bool); ok { | ||
fn() | ||
} | ||
} | ||
} | ||
|
||
func (c *Conn) clearReadTimeout() { | ||
if closer := c.readTimeoutCloser.Load(); closer != nil { | ||
if fn, ok := closer.(func() bool); ok { | ||
fn() | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
module github.com/coder/websocket | ||
|
||
go 1.19 | ||
go 1.21 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
module github.com/coder/websocket/examples | ||
|
||
go 1.19 | ||
go 1.21 | ||
|
||
replace github.com/coder/websocket => ../.. | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
atomic.Pointer
would be cleaner.atomic.Value
still stores the value as a pointer, it's just not explicit. The upside ofatomic.Pointer
is that it requires no type casting.