From cb780d82d51007326bb745663840696fee54bfbd Mon Sep 17 00:00:00 2001 From: David Norton Date: Fri, 6 Mar 2015 09:38:21 -0500 Subject: [PATCH] fix #1180: race in startStateLoop --- CHANGELOG.md | 1 + raft/log.go | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edb32a5e76..da135bfb84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Bugfixes - [#1867](https://github.com/influxdb/influxdb/pull/1867): Fix race accessing topic replicas map +- [#1864](https://github.com/influxdb/influxdb/pull/1864): fix race in startStateLoop ## v0.9.0-rc8 [2015-03-05] diff --git a/raft/log.go b/raft/log.go index 026869d628..2933c22484 100644 --- a/raft/log.go +++ b/raft/log.go @@ -14,7 +14,6 @@ import ( "net/url" "os" "path/filepath" - "runtime" "runtime/debug" "sort" "strconv" @@ -627,20 +626,21 @@ func (l *Log) Leave() error { // Returns once the state has transitioned to the initial state passed in. func (l *Log) startStateLoop(closing <-chan struct{}, state State) { l.wg.Add(1) - go l.stateLoop(closing, state) + stateChanged := make(chan struct{}) + go l.stateLoop(closing, state, stateChanged) // Wait until state change. - for { - if l.state == state { - break - } - runtime.Gosched() - } + <-stateChanged } // stateLoop runs in a separate goroutine and runs the appropriate state loop. -func (l *Log) stateLoop(closing <-chan struct{}, state State) { +func (l *Log) stateLoop(closing <-chan struct{}, state State, stateChanged chan struct{}) { defer l.wg.Done() + + l.Logger.Printf("log state change: %s => %s", l.state, state) + l.state = state + close(stateChanged) + for { // Transition to new state. l.Logger.Printf("log state change: %s => %s", l.state, state)