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

ConcurrentModificationException on event firing #130

Open
azhuchkov opened this issue Jun 18, 2021 · 0 comments
Open

ConcurrentModificationException on event firing #130

azhuchkov opened this issue Jun 18, 2021 · 0 comments

Comments

@azhuchkov
Copy link

Sometimes (rarely) I encounter the following exception:

java.util.ConcurrentModificationException: null
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909) ~[na:1.8.0_161]
	at java.util.ArrayList$Itr.next(ArrayList.java:859) ~[na:1.8.0_161]
	at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1042) ~[na:1.8.0_161]
	at org.squirrelframework.foundation.fsm.impl.StateImpl.entry(StateImpl.java:128) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.TimedStateImpl.entry(TimedStateImpl.java:17) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.StateImpl.enterShallow(StateImpl.java:271) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.TimedStateImpl.enterShallow(TimedStateImpl.java:17) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.StateImpl.enterHistoryNone(StateImpl.java:295) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.StateImpl.enterByHistory(StateImpl.java:248) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.TransitionImpl.internalFire(TransitionImpl.java:203) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.StateImpl.internalFire(StateImpl.java:419) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.TimedStateImpl.internalFire(TimedStateImpl.java:17) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.AbstractStateMachine.processEvent(AbstractStateMachine.java:161) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.AbstractStateMachine.processEvents(AbstractStateMachine.java:215) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.AbstractStateMachine.internalFire(AbstractStateMachine.java:248) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.AbstractStateMachine.fire(AbstractStateMachine.java:268) ~[squirrel-foundation-0.3.8.jar:na]
	at org.squirrelframework.foundation.fsm.impl.AbstractStateMachine.fire(AbstractStateMachine.java:279) ~[squirrel-foundation-0.3.8.jar:na]

Since I am unable to find code paths of action list modifications during FSM execution, I guess this is a memory visibility issue. The quick fix I use:

  static {
    // must be called before org.squirrelframework.foundation.fsm.impl.FSM.newActions()
    SquirrelProvider.getInstance().register(Actions.class, ThreadSafeActionsImpl.class);
  }

  public static class ThreadSafeActionsImpl<T extends StateMachine<T, S, E, C>, S, E, C>
      implements Actions<T, S, E, C> {

    private static final Comparator<Action<?, ?, ?, ?>> ACTION_COMPARATOR =
        (o1, o2) -> o2.weight() - o1.weight();

    private final SortedSet<Action<T, S, E, C>> actions =
        Collections.synchronizedSortedSet(new TreeSet<>(ACTION_COMPARATOR));

    @Override
    public void add(Action<T, S, E, C> newAction) {
      actions.add(newAction);
    }

    @Override
    public void addAll(List<? extends Action<T, S, E, C>> newActions) {
      actions.addAll(newActions);
    }

    @Override
    public List<Action<T, S, E, C>> getAll() {
      return Collections.unmodifiableList(new ArrayList<>(actions));
    }

    @Override
    public void clear() {
      throw new UnsupportedOperationException("not implemented");
    }
  }
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

No branches or pull requests

1 participant