-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Break grabLockOrStop into two pieces to facilitate investigating deadlocks #17187
Conversation
…locks. Without this change, the "grab" goroutine looks the same regardless of who was calling grabLockOrStop, so there's no way to identify one of the deadlock parties.
It looks like there's a test using the old way of checking |
No, I kept the old func around for now, in part so I don't break ent when we merge to it. I might get rid of it in another pass later. |
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.
Looks good to me. I just posted a nit suggestion.
defer close(l.doneCh) | ||
l.lockFunc() | ||
|
||
// The parent goroutine may or may not be waiting. |
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.
Would it worth adding godoc for this function explaining how this function should be used? Although all the examples usages show that, it is not clear maybe for a future developer as to why this function should be used in a separate go routine.
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.
Good idea, added.
Right, I noticed that the function itself is still there, but the way the function is used has changed, no? Previously it was: stopped := grabLockOrStop(c.stateLock.RLock, c.stateLock.RUnlock, stopCh)
if stopped {
// something
} And now it's: l := newLockGrabber(c.stateLock.RLock, c.stateLock.RUnlock, stopCh)
go l.grab()
if stopped := l.lockOrStop(); stopped {
// something
} Everything in this PR uses the new way and that test still uses the old way. |
Without this change, the "grab" locking goroutine looks the same regardless of who was calling grabLockOrStop, so there's no way to identify one of the deadlock parties.
Example of the confusion we're trying to eliminate: