From ce806478989b60ba0885f7981cf6dcc6443b192c Mon Sep 17 00:00:00 2001 From: Bradley Baetz Date: Sun, 9 Jan 2000 02:38:24 +0000 Subject: [PATCH] Fixed race condition between app and wine in WAVE_mciPlay. --- dlls/winmm/mciwave/mciwave.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/dlls/winmm/mciwave/mciwave.c b/dlls/winmm/mciwave/mciwave.c index 2c08019e13a..6bd66e18d45 100644 --- a/dlls/winmm/mciwave/mciwave.c +++ b/dlls/winmm/mciwave/mciwave.c @@ -28,7 +28,7 @@ typedef struct { MCI_WAVE_OPEN_PARMSA openParms; LPWAVEFORMATEX lpWaveFormat; BOOL fInput; /* FALSE = Output, TRUE = Input */ - WORD dwStatus; /* one from MCI_MODE_xxxx */ + volatile WORD dwStatus; /* one from MCI_MODE_xxxx */ DWORD dwMciTimeFormat;/* One of the supported MCI_FORMAT_xxxx */ DWORD dwFileOffset; /* Offset of chunk in mmio file */ DWORD dwLength; /* number of bytes in chunk for playing */ @@ -432,7 +432,7 @@ static DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParm if (oldStat == MCI_MODE_PAUSE) dwRet = (wmw->fInput) ? waveInReset(wmw->hWave) : waveOutReset(wmw->hWave); } - while (((volatile WINE_MCIWAVE*)wmw)->dwStatus != MCI_MODE_STOP) + while (wmw->dwStatus != MCI_MODE_STOP) Sleep(10); break; } @@ -550,19 +550,26 @@ static DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) return MCIERR_FILE_NOT_FOUND; } - if (!(dwFlags & MCI_WAIT)) { - return MCI_SendCommandAsync(wmw->wNotifyDeviceID, MCI_PLAY, dwFlags, - (DWORD)lpParms, sizeof(MCI_PLAY_PARMS)); - } - - if (wmw->dwStatus != MCI_MODE_STOP) { if (wmw->dwStatus == MCI_MODE_PAUSE) { /* FIXME: parameters (start/end) in lpParams may not be used */ return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms); } + + /** This function will be called again by a thread when async is used. + * We have to set MCI_MODE_PLAY before we do this so that the app can spin + * on MCI_STATUS, so we have to allow it here if we're not going to start this thread. + */ + if ((wmw->dwStatus != MCI_MODE_STOP) && ((wmw->dwStatus != MCI_MODE_PLAY) && (dwFlags & MCI_WAIT))) { return MCIERR_INTERNAL; } + wmw->dwStatus = MCI_MODE_PLAY; + + if (!(dwFlags & MCI_WAIT)) { + return MCI_SendCommandAsync(wmw->wNotifyDeviceID, MCI_PLAY, dwFlags, + (DWORD)lpParms, sizeof(MCI_PLAY_PARMS)); + } + end = 0xFFFFFFFF; if (lpParms && (dwFlags & MCI_FROM)) { wmw->dwPosition = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwFrom); @@ -625,7 +632,6 @@ static DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) wmw->dwEventCount = 1L; /* for first buffer */ TRACE("Playing (normalized) from byte=%lu for %lu bytes\n", wmw->dwPosition, left); - wmw->dwStatus = MCI_MODE_PLAY; /* FIXME: this doesn't work if wmw->dwPosition != 0 */ while (left > 0 && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {