Commit 5dd8fbe9 authored by David Reid's avatar David Reid

Improvements to the main worker thread.

  * If starting the backend fails, don't attempt to enter the data loop
  * If stopping the backend fails, don't fire the stop callback.
parent 07e56c70
...@@ -32810,7 +32810,8 @@ static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData) ...@@ -32810,7 +32810,8 @@ static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData)
ma_event_signal(&pDevice->stopEvent); ma_event_signal(&pDevice->stopEvent);
for (;;) { /* <-- This loop just keeps the thread alive. The main audio loop is inside. */ for (;;) { /* <-- This loop just keeps the thread alive. The main audio loop is inside. */
ma_stop_proc onStop; ma_result startResult;
ma_result stopResult; /* <-- This will store the result from onDeviceStop(). If it returns an error, we don't fire the onStop callback. */
/* We wait on an event to know when something has requested that the device be started and the main loop entered. */ /* We wait on an event to know when something has requested that the device be started and the main loop entered. */
ma_event_wait(&pDevice->wakeupEvent); ma_event_wait(&pDevice->wakeupEvent);
...@@ -32832,10 +32833,14 @@ static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData) ...@@ -32832,10 +32833,14 @@ static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData)
/* If the device has a start callback, start it now. */ /* If the device has a start callback, start it now. */
if (pDevice->pContext->callbacks.onDeviceStart != NULL) { if (pDevice->pContext->callbacks.onDeviceStart != NULL) {
ma_result result = pDevice->pContext->callbacks.onDeviceStart(pDevice); startResult = pDevice->pContext->callbacks.onDeviceStart(pDevice);
if (result != MA_SUCCESS) { } else {
pDevice->workResult = result; /* Failed to start the device. */ startResult = MA_SUCCESS;
} }
if (startResult != MA_SUCCESS) {
pDevice->workResult = startResult;
continue; /* Failed to start. Loop back to the start and wait for something to happen (pDevice->wakeupEvent). */
} }
/* Make sure the state is set appropriately. */ /* Make sure the state is set appropriately. */
...@@ -32849,36 +32854,26 @@ static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData) ...@@ -32849,36 +32854,26 @@ static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData)
ma_device_audio_thread__default_read_write(pDevice); ma_device_audio_thread__default_read_write(pDevice);
} }
/* /* Getting here means we have broken from the main loop which happens the application has requested that device be stopped. */
Getting here means we have broken from the main loop which happens the application has requested that device be stopped. Note that this if (pDevice->pContext->callbacks.onDeviceStop != NULL) {
may have actually already happened above if the device was lost and miniaudio has attempted to re-initialize the device. In this case we stopResult = pDevice->pContext->callbacks.onDeviceStop(pDevice);
don't want to be doing this a second time. } else {
*/ stopResult = MA_SUCCESS; /* No stop callback with the backend. Just assume successful. */
if (ma_device_get_state(pDevice) != MA_STATE_UNINITIALIZED) {
if (pDevice->pContext->callbacks.onDeviceStop != NULL) {
pDevice->pContext->callbacks.onDeviceStop(pDevice);
}
}
/* After the device has stopped, make sure an event is posted. */
onStop = pDevice->onStop;
if (onStop) {
onStop(pDevice);
} }
/* /*
A function somewhere is waiting for the device to have stopped for real so we need to signal an event to allow it to continue. Note that After the device has stopped, make sure an event is posted. Don't post an onStop event if
it's possible that the device has been uninitialized which means we need to _not_ change the status to stopped. We cannot go from an stopping failed. This can happen on some backends when the underlying stream has been
uninitialized state to stopped state. stopped due to the device being physically unplugged or disabled via an OS setting.
*/ */
if (ma_device_get_state(pDevice) != MA_STATE_UNINITIALIZED) { if (pDevice->onStop && stopResult != MA_SUCCESS) {
ma_device__set_state(pDevice, MA_STATE_STOPPED); pDevice->onStop(pDevice);
ma_event_signal(&pDevice->stopEvent);
} }
}
/* Make sure we aren't continuously waiting on a stop event. */ /* A function somewhere is waiting for the device to have stopped for real so we need to signal an event to allow it to continue. */
ma_event_signal(&pDevice->stopEvent); /* <-- Is this still needed? */ ma_device__set_state(pDevice, MA_STATE_STOPPED);
ma_event_signal(&pDevice->stopEvent);
}
#ifdef MA_WIN32 #ifdef MA_WIN32
ma_CoUninitialize(pDevice->pContext); ma_CoUninitialize(pDevice->pContext);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment