This has a whiff of the double-checked locking anti-pattern.  I can't  
see a way where it would really bite us in this case, but that anti- 
pattern has several subtleties.  So, I just wanted to prompt people to  
double-check it (pun acknowledged).

Cheers,
Ken

On Mar 18, 2008, at 7:44 AM, Alexandre Julliard wrote:
> Module: wine
> Branch: master
> Commit: 15907b5035ea7f03b369a0463ab1f6ac2b24704e
> URL:    
> http://source.winehq.org/git/wine.git/?a=commit;h=15907b5035ea7f03b369a0463ab1f6ac2b24704e
>
> Author: Maarten Lankhorst <[EMAIL PROTECTED]>
> Date:   Mon Mar 17 13:15:42 2008 -0700
>
> winmm: Fix midi deadlock by not holding lock on release.
>
> ---
>
> 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;
>     }
>
>
>
>



Reply via email to