fix shutdown stuck or panic

This commit is contained in:
yusing 2025-01-03 03:08:21 +08:00
parent 9f71fc2dd5
commit ba8705fb84
3 changed files with 12 additions and 8 deletions

View file

@ -12,6 +12,8 @@ func (t *Task) addCallback(about string, fn func(), waitSubTasks bool) {
defer t.mu.Unlock() defer t.mu.Unlock()
if t.callbacks == nil { if t.callbacks == nil {
t.callbacks = make(map[*Callback]struct{}) t.callbacks = make(map[*Callback]struct{})
}
if t.callbacksDone == nil {
t.callbacksDone = make(chan struct{}) t.callbacksDone = make(chan struct{})
} }
t.callbacks[&Callback{fn, about, waitSubTasks}] = struct{}{} t.callbacks[&Callback{fn, about, waitSubTasks}] = struct{}{}
@ -28,14 +30,15 @@ func (t *Task) addChildCount() {
} }
func (t *Task) subChildCount() { func (t *Task) subChildCount() {
if atomic.AddUint32(&t.children, ^uint32(0)) == 0 { switch atomic.AddUint32(&t.children, ^uint32(0)) {
case 0:
close(t.childrenDone) close(t.childrenDone)
case ^uint32(0):
panic("negative child count")
} }
} }
func (t *Task) runCallbacks() { func (t *Task) runCallbacks() {
t.mu.Lock()
defer t.mu.Unlock()
if len(t.callbacks) == 0 { if len(t.callbacks) == 0 {
return return
} }

View file

@ -117,9 +117,7 @@ func (t *Task) finish(reason any) {
Strs("callbacks", t.listCallbacks()). Strs("callbacks", t.listCallbacks()).
Msg("Timeout waiting for callbacks to finish") Msg("Timeout waiting for callbacks to finish")
} }
if t.finished != nil { close(t.finished)
close(t.finished)
}
if t == root { if t == root {
return return
} }

View file

@ -30,9 +30,12 @@ func RootTask(name string, needFinish ...bool) *Task {
} }
func newRoot() *Task { func newRoot() *Task {
t := &Task{name: "root"} t := &Task{
name: "root",
childrenDone: make(chan struct{}),
finished: make(chan struct{}),
}
t.ctx, t.cancel = context.WithCancelCause(context.Background()) t.ctx, t.cancel = context.WithCancelCause(context.Background())
t.callbacks = make(map[*Callback]struct{})
return t return t
} }