mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Tighten up the audio thread.
This should close a hole that could possibly result in the audio thread getting stuck if the `MA_DEVICE_OP_UNINIT` operation posted from `ma_device_uninit()` fails.
This commit is contained in:
+23
-5
@@ -48126,16 +48126,32 @@ static ma_thread_result MA_THREADCALL ma_audio_thread(void* pData)
|
||||
goto end_audio_thread;
|
||||
}
|
||||
|
||||
|
||||
for (;;) {
|
||||
result = ma_device_op_queue_next(&pDevice->opQueue, MA_BLOCKING_MODE_BLOCKING, &pOp);
|
||||
ma_blocking_mode blockingMode = MA_BLOCKING_MODE_BLOCKING;
|
||||
|
||||
/* If the device has put into an uninitialized state we will make sure the thread is always terminated. */
|
||||
if (ma_device_get_status(pDevice) == ma_device_status_uninitialized) {
|
||||
blockingMode = MA_BLOCKING_MODE_NON_BLOCKING;
|
||||
}
|
||||
|
||||
result = ma_device_op_queue_next(&pDevice->opQueue, blockingMode, &pOp);
|
||||
if (result != MA_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
This is a safety mechanism to avoid an infinite loop. If the device has been marked as uninitialized, but we haven't
|
||||
got anything in the queue, we'll get out of the loop to make sure we don't get stuck. This can *technically* happen
|
||||
if pushing the MA_DEVICE_OP_UNINIT in `ma_device_uninit()` fails, although it'll be exceptionally rare.
|
||||
*/
|
||||
if (result == MA_NO_DATA_AVAILABLE) {
|
||||
if (ma_device_get_status(pDevice) == ma_device_status_uninitialized) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* */ if (pOp->type == MA_DEVICE_OP_UNINIT) {
|
||||
ma_device_op_do_uninit(pDevice, pOp->pCompletionEvent);
|
||||
break;
|
||||
break; /* Breaking from the loop will trigger an uninit. */
|
||||
} else if (pOp->type == MA_DEVICE_OP_START) {
|
||||
/* We should never be attempting to start the device unless it's in a stopped state. */
|
||||
MA_ASSERT(ma_device_get_status(pDevice) == ma_device_status_starting);
|
||||
@@ -48160,7 +48176,6 @@ static ma_thread_result MA_THREADCALL ma_audio_thread(void* pData)
|
||||
if (result == MA_SUCCESS) {
|
||||
if (pOp->type == MA_DEVICE_OP_UNINIT) {
|
||||
ma_device_op_do_stop(pDevice, NULL);
|
||||
ma_device_op_do_uninit(pDevice, pOp->pCompletionEvent);
|
||||
break; /* <-- This gets out of the op queue loop and terminates the audio thread. */
|
||||
} else if (pOp->type == MA_DEVICE_OP_STOP) {
|
||||
ma_device_op_do_stop(pDevice, pOp->pCompletionEvent);
|
||||
@@ -48195,6 +48210,9 @@ static ma_thread_result MA_THREADCALL ma_audio_thread(void* pData)
|
||||
}
|
||||
}
|
||||
|
||||
/* When we leave the loop we always need to uninitialize the backend. */
|
||||
ma_device_op_do_uninit(pDevice, pOp->pCompletionEvent);
|
||||
|
||||
end_audio_thread:
|
||||
#ifdef MA_WIN32
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user