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 race conditions in conn.go #134

Merged
merged 7 commits into from
Sep 23, 2017
Merged

Conversation

judwhite
Copy link
Contributor

@judwhite judwhite commented Sep 23, 2017

Commits are separated for easier review. Commit messages have details on the thought process.

I just came across this package tonight, so I'm unfamiliar with its use in real scenarios. I may also be unfamiliar with nuances in the code. If someone could try this in their setup or recommend which use cases need tests I'll happily add them.

/cc @johnweldon @liggitt

- closeCount renamed to closing; acts as atomic bool
- once replaced with atomic.CompareAndSwapUint32 in setClosing method
- wgSender removed:
  - Close could call wgSender.Wait while another goroutine is about to
    call wgSender.Add; this is detected by the race detector as a race
    condition if Wait hasn't yet returned. the WaitGroup documentation
    also lists this scenario as an error.
  - the intent appears to be to let all messages queue in the buffered
    chan 'chanMessage' before sending MessageQuit. the WaitGroup could
    reach 0 and be incremented again by a goroutine which successfully
    passed isClosing, therefore the WaitGroup isn't a strong enough
    guarantee. this is addressed in the next commit.
@judwhite
Copy link
Contributor Author

Related #112, #127

Copy link
Member

@johnweldon johnweldon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Thank you!

@liggitt
Copy link
Contributor

liggitt commented Sep 23, 2017

Nit on defer unlock. Lgtm otherwise, thanks

- in order to guarantee the Op: MessageQuit is the last in chanMessage
  we need to lock messageMutex (or any mutex) before setting 'closing'
  in the Close method and before checking it in the sendProcessMessage
  method.
- there may be other ways to do this, such as sending the close message
  to a different channel and then draining the chanMessage channel.
  this would require more accounting work
- remove l.chanMessageID != nil check; setting the chan to
  nil was removed in 3bda2b4
- change chanConfirm to chan struct{}; remove send, just close
- log.Print -> log.Println
- since the intention is to close chanMessage after calling Close and
  receiving on chanConfirm (in the defer of processMessages) the
  channel should not be closed in the for/select loop
@judwhite
Copy link
Contributor Author

@liggitt Done.

@johnweldon johnweldon merged commit 3de5b9b into go-ldap:master Sep 23, 2017
liggitt added a commit that referenced this pull request Nov 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants