mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-23 08:44:04 +02:00
WASAPI: Fix a potential deadlock with exclusive + duplex mode.
This commit is contained in:
+7
-19
@@ -15254,13 +15254,6 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice)
|
|||||||
|
|
||||||
/* The process is to map the playback buffer and fill it as quickly as possible from input data. */
|
/* The process is to map the playback buffer and fill it as quickly as possible from input data. */
|
||||||
if (pMappedDeviceBufferPlayback == NULL) {
|
if (pMappedDeviceBufferPlayback == NULL) {
|
||||||
/* WASAPI is weird with exclusive mode. You need to wait on the event _before_ querying the available frames. */
|
|
||||||
if (pDevice->playback.shareMode == ma_share_mode_exclusive) {
|
|
||||||
if (WaitForSingleObject(pDevice->wasapi.hEventPlayback, MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS) != WAIT_OBJECT_0) {
|
|
||||||
return MA_ERROR; /* Wait failed. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ma_device__get_available_frames__wasapi(pDevice, (ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, &framesAvailablePlayback);
|
result = ma_device__get_available_frames__wasapi(pDevice, (ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, &framesAvailablePlayback);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
@@ -15276,18 +15269,6 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there's no frames available in the playback device we need to wait for more. */
|
|
||||||
if (framesAvailablePlayback == 0) {
|
|
||||||
/* In exclusive mode we waited at the top. */
|
|
||||||
if (pDevice->playback.shareMode != ma_share_mode_exclusive) {
|
|
||||||
if (WaitForSingleObject(pDevice->wasapi.hEventPlayback, MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS) != WAIT_OBJECT_0) {
|
|
||||||
return MA_ERROR; /* Wait failed. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We're ready to map the playback device's buffer. We don't release this until it's been entirely filled. */
|
/* We're ready to map the playback device's buffer. We don't release this until it's been entirely filled. */
|
||||||
hr = ma_IAudioRenderClient_GetBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, framesAvailablePlayback, &pMappedDeviceBufferPlayback);
|
hr = ma_IAudioRenderClient_GetBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, framesAvailablePlayback, &pMappedDeviceBufferPlayback);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@@ -15300,6 +15281,7 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice)
|
|||||||
mappedDeviceBufferFramesRemainingPlayback = framesAvailablePlayback;
|
mappedDeviceBufferFramesRemainingPlayback = framesAvailablePlayback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mappedDeviceBufferFramesRemainingPlayback > 0) {
|
||||||
/* At this point we should have a buffer available for output. We need to keep writing input samples to it. */
|
/* At this point we should have a buffer available for output. We need to keep writing input samples to it. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Try grabbing some captured data if we haven't already got a mapped buffer. */
|
/* Try grabbing some captured data if we haven't already got a mapped buffer. */
|
||||||
@@ -15517,6 +15499,7 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If at this point we've run out of data we need to release the buffer. */
|
/* If at this point we've run out of data we need to release the buffer. */
|
||||||
@@ -15554,6 +15537,11 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice)
|
|||||||
c89atomic_exchange_8(&pDevice->wasapi.isStartedPlayback, MA_TRUE);
|
c89atomic_exchange_8(&pDevice->wasapi.isStartedPlayback, MA_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure the device has started before waiting. */
|
||||||
|
if (WaitForSingleObject(pDevice->wasapi.hEventPlayback, MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS) != WAIT_OBJECT_0) {
|
||||||
|
return MA_ERROR; /* Wait failed. */
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user