Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-25958

Multi-target transition wrongly activates initial states inside parallel state group

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P3: Somewhat important
    • 5.0.0
    • 4.8.1
    • Core: State Machine
    • None
    • c4cef6fae9f2a55f21fc9517855dfcf659c89081

    Description

      Let's have following state machine ('@' marks initial states of each compound state):

                                +---------------------------------------+
                                |              s2 (parallel)            |
                                +---------------------------------------+
                                |                                       |
                                |   +-------------------------+         |
                                |   |           s21           |         |
                                |   +-------------------------+         |
                                |   |                         |         |
                                |   |  +----+          +----+ |         |
                             --------->|s211|    @---->|s212| |         |
                            /   |   |  +----+          +----+ |         |
                           /    |   |                         |         |
                          /     |   +-------------------------+         |
             +----+  t1  /      |                                       |
       @---->| s1 |-----+       |          +------------------------+   |
             +----+      \      |          |          s22           |   |
                          \     |          +------------------------+   |
                           \    |          |                        |   |
                            \   |          |  +----+         +----+ |   |
                             ---------------->|s221|   @---->|s222| |   |
                                |          |  +----+         +----+ |   |
                                |          |                        |   |
                                |          +------------------------+   |
                                |                                       |
                                +---------------------------------------+
      

      See multitarget.cpp for implementation.

      Running the example program outputs:

      virtual void MyState::onEntry(QEvent*): s1
      virtual void MyState::onExit(QEvent*): s1
      virtual void NullTransition::onTransition(QEvent*): t
      virtual void MyState::onEntry(QEvent*): s2
      virtual void MyState::onEntry(QEvent*): s211
      virtual void MyState::onEntry(QEvent*): s22
      virtual void MyState::onEntry(QEvent*): s21
      virtual void MyState::onEntry(QEvent*): s222
      virtual void MyState::onEntry(QEvent*): s221
      

      So it can be seen that after transition t1 is invoked, both s221 and s222 are entered, but it should never happen that two children inside a compound state are active at the same time. One would expect that t1 will make active only s2, s21, s211, s22 and s221.

      Apparently, the QStateMachine implementation first selects s211 for activation. Then it selects all its ancestors, making s21 and s2 active. If finds out that s2 is a parallel state group, so it activates all its children that are not yet active, in the example s22. Because s22 is a compound state, state machine activates also its initial state s222 - it's not aware that there is s221 going to be activated, right after s1-s211 component of transition t1 is processed. So finally, we will end up with both s211 and s222 active.

      The state machine should ensure that compound state's initial state is entered only when there isn't any of its siblings being activated by a multi target transition.

      Workaround

      Seems that there is a possible workaround for this bug, see multitarget-workaround.cpp. When transition is invoked, it temporarily replaces the target's parent initial state with the target state itself. This prevents the initial state from being wrongly selected. When onEntry method of target is called, it restores the original initial state.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            kenthans Kent Hansen (Inactive)
            jadam Jakub Adam
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes