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:
David Reid
2026-02-04 14:20:42 +10:00
parent 93e74aaf91
commit 1e2427f5f7
+23 -5
View File
@@ -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
{