Skip to content

Commit 8482527

Browse files
authored
Fix panic in Task FrameWork, fixes #5034 (#5081)
1 parent 669228c commit 8482527

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

worker/draft.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ const (
9797
// startTask is used to check whether an op is already going on.
9898
// If rollup is going on, we cancel and wait for rollup to complete
9999
// before we return. If the same task is already going, we return error.
100+
// You should only call Done() on the returned closer. Calling other
101+
// functions (such as SignalAndWait) for closer could result in panics.
102+
// For more details, see GitHub issue #5034.
100103
func (n *node) startTask(id op) (*y.Closer, error) {
101104
n.opsLock.Lock()
102105
defer n.opsLock.Unlock()
@@ -126,6 +129,8 @@ func (n *node) startTask(id op) (*y.Closer, error) {
126129
case opSnapshot, opIndexing:
127130
for otherId, otherCloser := range n.ops {
128131
if otherId == opRollup {
132+
// We set to nil so that stopAllTasks doesn't call SignalAndWait again.
133+
n.ops[opRollup] = nil
129134
otherCloser.SignalAndWait()
130135
} else {
131136
return nil, errors.Errorf("operation %s is already running", otherId)
@@ -159,14 +164,12 @@ func (n *node) stopAllTasks() {
159164
defer n.closer.Done() // CLOSER:1
160165
<-n.closer.HasBeenClosed()
161166

162-
var closers []*y.Closer
163167
n.opsLock.Lock()
168+
defer n.opsLock.Unlock()
164169
for _, closer := range n.ops {
165-
closers = append(closers, closer)
166-
}
167-
n.opsLock.Unlock()
168-
169-
for _, closer := range closers {
170+
if closer == nil {
171+
continue
172+
}
170173
closer.SignalAndWait()
171174
}
172175
glog.Infof("Stopped all ongoing registered tasks.")

0 commit comments

Comments
 (0)