@@ -97,6 +97,7 @@ type Machine struct {
9797 stateNames S
9898 stateNamesExport S
9999 handlersLock sync.Mutex
100+ loopLock sync.Mutex
100101 handlers []* handler
101102 clock Clock
102103 cancel context.CancelFunc
@@ -396,6 +397,9 @@ func (m *Machine) doDispose(force bool) {
396397 m .tracers = nil
397398 go func () {
398399 time .Sleep (100 * time .Millisecond )
400+ m .loopLock .Lock ()
401+ defer m .loopLock .Unlock ()
402+
399403 closeSafe (m .handlerEnd )
400404 closeSafe (m .handlerPanic )
401405 closeSafe (m .handlerStart )
@@ -1620,21 +1624,25 @@ func (m *Machine) MustParseStates(states S) S {
16201624 }
16211625
16221626 // check if all states are defined in m.Struct
1623- // TODO optimize?
1624- ret := make (S , len (states ))
16251627 seen := make (map [string ]struct {})
1628+ dups := false
16261629 for i := range states {
16271630 if _ , ok := m.schema [states [i ]]; ! ok {
16281631 panic (fmt .Errorf (
16291632 "%w: %s not defined in schema for %s" , ErrStateMissing ,
16301633 states [i ], m .id ))
16311634 }
16321635 if _ , ok := seen [states [i ]]; ! ok {
1633- ret = append (ret , states [i ])
16341636 seen [states [i ]] = struct {}{}
1637+ } else {
1638+ // mark as duplicated
1639+ dups = true
16351640 }
16361641 }
16371642
1643+ if dups {
1644+ return slicesUniq (states )
1645+ }
16381646 return states
16391647}
16401648
@@ -2546,14 +2554,17 @@ func (m *Machine) handlerLoop() {
25462554 return
25472555 }
25482556
2557+ m .loopLock .Lock ()
2558+
25492559 // pass the result to handlerLoop
25502560 select {
25512561 case <- m .ctx .Done ():
25522562 m .handlerLoopDone ()
2563+ m .loopLock .Unlock ()
25532564 return
25542565
25552566 case m .handlerEnd <- ret :
2556- // pass
2567+ m . loopLock . Unlock ()
25572568 }
25582569 }
25592570 }
@@ -2675,8 +2686,8 @@ func (m *Machine) IsQueued(mutationType MutationType, states S,
26752686}
26762687
26772688// IsQueuedAbove allows for rate-limiting of mutations for a specific state.
2678- func (m * Machine ) IsQueuedAbove (threshold int , mutationType MutationType , states S ,
2679- withoutArgsOnly bool , statesStrictEqual bool , startIndex int ,
2689+ func (m * Machine ) IsQueuedAbove (threshold int , mutationType MutationType ,
2690+ states S , withoutArgsOnly bool , statesStrictEqual bool , startIndex int ,
26802691) bool {
26812692 if m .disposed .Load () {
26822693 return false
0 commit comments