Skip to content
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

Fix a goroutine misusage in the implementation of Worker.Subscribe() #1775

Merged
merged 1 commit into from
Nov 29, 2016

Conversation

AkihiroSuda
Copy link
Member

Fix moby/moby#28915

Signed-off-by: Akihiro Suda suda.akihiro@lab.ntt.co.jp

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
@codecov-io
Copy link

codecov-io commented Nov 29, 2016

Current coverage is 55.05% (diff: 0.00%)

Merging #1775 into master will decrease coverage by 0.03%

@@             master      #1775   diff @@
==========================================
  Files           102        102          
  Lines         16871      16871          
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
- Hits           9294       9288     -6   
- Misses         6419       6428     +9   
+ Partials       1158       1155     -3   

Sunburst

Powered by Codecov. Last update 2422b48...35324fd

@thaJeztah
Copy link
Member

ping @aluzzardi ptal

@LK4D4
Copy link
Contributor

LK4D4 commented Nov 29, 2016

LGTM

2 similar comments
@dongluochen
Copy link
Contributor

LGTM

@aaronlehmann
Copy link
Collaborator

LGTM

@stevvooe
Copy link
Contributor

stevvooe commented Dec 1, 2016

Classic!

@AkihiroSuda
Copy link
Member Author

BTW, is there any static code checking tool for this "common mistake"?

@aaronlehmann
Copy link
Collaborator

I don't know of any, but I think it would be a very good addition to go vet.

@stevvooe
Copy link
Contributor

stevvooe commented Dec 1, 2016

@AkihiroSuda @aaronlehmann Just don't do it. ;)

The best way to understand why this is to think of the for loop variables like this:

{ // enclosing block
  var tm *taskManager
  for tm = range taskManagers {
    // tm gets a new value on each iteration.
  }
}

Checkout https://play.golang.org/p/Bat8jtGgEh. It results in all goroutines printing last value of i. tm as a pointer works the same way. The way around this is to create new variable, on each loop, and let that get closed:

{ // enclosing block
  var tm *taskManager
  for tm = range taskManagers {
     tm := tm
    // tm gets a new value on each iteration.
  }
}

The above creates a new tm per loop scope, which can get closed over independently. The best way to think of this is that these variables are members of for loop's scope, not the scope of each run of the for loop (this makes a lot of sense of memory efficiency).

Really, this could be caught with the race detector.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants