From 6f82eea6b801d33f0fd66f95ad8109a634bb840b Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 17 Mar 2008 13:15:42 -0700 Subject: [PATCH] winmm: Fix deadlock with mciseq by not holding lock when closing all devices --- dlls/winmm/mci.c | 22 ++++++++++++++-------- 1 files changed, 14 insertions(+), 8 deletions(-) diff --git a/dlls/winmm/mci.c b/dlls/winmm/mci.c index b7b5ac2..c792d18 100644 --- a/dlls/winmm/mci.c +++ b/dlls/winmm/mci.c @@ -1767,19 +1767,25 @@ static DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms TRACE("(%04x, %08X, %p)\n", wDevID, dwParam, lpParms); if (wDevID == MCI_ALL_DEVICE_ID) { - LPWINE_MCIDRIVER next; - - EnterCriticalSection(&WINMM_cs); /* FIXME: shall I notify once after all is done, or for * each of the open drivers ? if the latest, which notif * to return when only one fails ? */ - for (wmd = MciDrivers; wmd; ) { - next = wmd->lpNext; - MCI_Close(wmd->wDeviceID, dwParam, lpParms); - wmd = next; + while (MciDrivers) { + /* Retrieve the device ID under lock, but send the message without, + * the driver might be calling some winmm functions from another + * thread before being fully stopped. + */ + EnterCriticalSection(&WINMM_cs); + if (!MciDrivers) + { + LeaveCriticalSection(&WINMM_cs); + break; + } + wDevID = MciDrivers->wDeviceID; + LeaveCriticalSection(&WINMM_cs); + MCI_Close(wDevID, dwParam, lpParms); } - LeaveCriticalSection(&WINMM_cs); return 0; } -- 1.5.4.1