Rémi Bernon (@rbernon) commented about dlls/mf/session.c:
session->state = SESSION_STATE_CLOSED; session_command_complete_with_event(session, MESessionClosed, MF_E_SHUTDOWN, NULL); break;
case COMMAND_STATE_SUBMITTED: case COMMAND_STATE_COMPLETE: if (session->state == SESSION_STATE_STARTED || session->state == SESSION_STATE_PAUSED) session_set_stopped(session, MESessionStopped, MF_E_SHUTDOWN); break;
```suggestion:-4+0 case COMMAND_STATE_COMPLETE: if (session->state == SESSION_STATE_STARTED || session->state == SESSION_STATE_PAUSED) session_set_stopped(session, MESessionStopped, MF_E_SHUTDOWN); break; case COMMAND_STATE_SUBMITTED: break; ```
This is where the issue may come from (ie: `session_set_stopped` calling `session_command_complete` which needs to avoid submitting the command again if it was already), and I think we can simply avoid doing anything if a command has been submitted already: either it's a command that will try to use the same source and it will handle the source shutdown eventually, or it's a command that will clear the topology and already do the proper state cleanup and update.
I believe this creates a stronger invariant for session_command_complete: it can safely complete the pending command if any, without having to special case `COMMAND_STATE_SUBMITTED` itself.