-
Notifications
You must be signed in to change notification settings - Fork 380
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
data race when deferring a Close() #333
Comments
Hm, it looks like We could probably just add the @eikenb do you know of anything off the top of your head that could break as a result? If not, I’ll setup a PR. |
Looking around there are many places where conn.Close() is called without the lock and I'm thinking that maybe these should all have locks. So I mean overridding Close() on the Basically something like... diff --git a/conn.go b/conn.go
index 62e585e..cfbc1d2 100644
--- a/conn.go
+++ b/conn.go
@@ -31,6 +31,12 @@ func (c *conn) sendPacket(m encoding.BinaryMarshaler) error {
return sendPacket(c, m)
}
+func (c *conn) Close() error {
+ c.Lock()
+ defer c.Unlock()
+ return c.WriteCloser.Close()
+}
+
type clientConn struct {
conn
wg sync.WaitGroup
@@ -67,9 +73,7 @@ func (c *clientConn) loop() {
// appropriate channel.
func (c *clientConn) recv() error {
defer func() {
- c.conn.Lock()
c.conn.Close()
- c.conn.Unlock()
}()
for {
typ, data, err := c.recvPacket() |
FYI, my work-around was this:
But yes, it would be better to do this properly upstream of me. |
Pushed up the PR to fix this. Probably overkill, but I thought I'd briefly fish for someone with the secret to reproducing data races. :) |
Yeah, reproducing data races is actually super hard to setup. It’s why I usually run through exhaustive proofs of behavior, rather than relying upon any sort of testing. It’s a lot more work, but tests for data races are often almost impossible to actually build. |
I am doing:
(where
s.SSHClient
is creating/storing/reusing an*ssh.Client
.)On rare occasion I get this:
Both goroutines are inside mutex-protected
myfunc
.So the issue here is that my own
Close()
call inmyfunc
's defer is competing with the internalClose()
call that gets triggered in the event of arecvPacket()
error.I'm not sure what I should do about this.
The text was updated successfully, but these errors were encountered: