From: Conor McCarthy cmccarthy@codeweavers.com
Fixes a regression introduced by 500470029b67a2a07b68e4ce8a134c6819b9b838 --- dlls/mf/session.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index cb45fceb714..483ea6f904f 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -56,6 +56,7 @@ struct session_op IUnknown IUnknown_iface; LONG refcount; enum session_command command; + BOOL submitted; union { struct @@ -473,7 +474,10 @@ static HRESULT session_submit_command(struct media_session *session, struct sess if (SUCCEEDED(hr = session_is_shut_down(session))) { if (list_empty(&session->commands) && !(session->presentation.flags & SESSION_FLAG_PENDING_COMMAND)) + { hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); + op->submitted = SUCCEEDED(hr); + } if (op->command == SESSION_CMD_SHUTDOWN) list_add_head(&session->commands, &op->entry); else @@ -859,6 +863,11 @@ static void session_clear_command_list(struct media_session *session)
LIST_FOR_EACH_ENTRY_SAFE(op, op2, &session->commands, struct session_op, entry) { + /* Checking this flag is unnecessary if this function is only called + * from the callback or upon release, but do it for consistency and + * in case a call from elsewhere is added. */ + if (op->submitted) + continue; list_remove(&op->entry); IUnknown_Release(&op->IUnknown_iface); } @@ -955,6 +964,7 @@ static void session_command_complete(struct media_session *session) { struct session_op *op; struct list *e; + HRESULT hr;
session->presentation.flags &= ~SESSION_FLAG_PENDING_COMMAND;
@@ -962,7 +972,8 @@ static void session_command_complete(struct media_session *session) if ((e = list_head(&session->commands))) { op = LIST_ENTRY(e, struct session_op, entry); - MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); + hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); + op->submitted = SUCCEEDED(hr); } }
@@ -1021,6 +1032,10 @@ static void session_purge_pending_commands(struct media_session *session) if (op->command == SESSION_CMD_CLEAR_TOPOLOGIES || op->command == SESSION_CMD_CLOSE || op->command == SESSION_CMD_SHUTDOWN) continue; + /* Once a command is submitted, the callback becomes responsible + * for removal from the list and release of the ref. */ + if (op->submitted) + continue; list_remove(&op->entry); IUnknown_Release(&op->IUnknown_iface); }