Commit bff79eb8 authored by David Reid's avatar David Reid

Fix some subtle multi-threading errors due to lacking atomic loads.

Public issue https://github.com/mackron/miniaudio/issues/237
parent db53994f
...@@ -4006,12 +4006,12 @@ struct ma_device ...@@ -4006,12 +4006,12 @@ struct ma_device
ma_uint32 originalPeriodSizeInMilliseconds; ma_uint32 originalPeriodSizeInMilliseconds;
ma_uint32 originalPeriods; ma_uint32 originalPeriods;
ma_performance_profile originalPerformanceProfile; ma_performance_profile originalPerformanceProfile;
ma_bool32 hasDefaultPlaybackDeviceChanged; /* <-- Make sure this is always a whole 32-bits because we use atomic assignments. */ volatile ma_bool32 hasDefaultPlaybackDeviceChanged; /* <-- Make sure this is always a whole 32-bits because we use atomic assignments. */
ma_bool32 hasDefaultCaptureDeviceChanged; /* <-- Make sure this is always a whole 32-bits because we use atomic assignments. */ volatile ma_bool32 hasDefaultCaptureDeviceChanged; /* <-- Make sure this is always a whole 32-bits because we use atomic assignments. */
ma_uint32 periodSizeInFramesPlayback; ma_uint32 periodSizeInFramesPlayback;
ma_uint32 periodSizeInFramesCapture; ma_uint32 periodSizeInFramesCapture;
ma_bool32 isStartedCapture; /* <-- Make sure this is always a whole 32-bits because we use atomic assignments. */ volatile ma_bool32 isStartedCapture; /* <-- Make sure this is always a whole 32-bits because we use atomic assignments. */
ma_bool32 isStartedPlayback; /* <-- Make sure this is always a whole 32-bits because we use atomic assignments. */ volatile ma_bool32 isStartedPlayback; /* <-- Make sure this is always a whole 32-bits because we use atomic assignments. */
ma_bool8 noAutoConvertSRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */ ma_bool8 noAutoConvertSRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
ma_bool8 noDefaultQualitySRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */ ma_bool8 noDefaultQualitySRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */
ma_bool8 noHardwareOffloading; ma_bool8 noHardwareOffloading;
...@@ -4162,14 +4162,14 @@ struct ma_device ...@@ -4162,14 +4162,14 @@ struct ma_device
ma_event operationCompletionEvent; ma_event operationCompletionEvent;
ma_semaphore operationSemaphore; ma_semaphore operationSemaphore;
ma_uint32 operation; ma_uint32 operation;
ma_result operationResult; volatile ma_result operationResult;
ma_timer timer; ma_timer timer;
double priorRunTime; double priorRunTime;
ma_uint32 currentPeriodFramesRemainingPlayback; ma_uint32 currentPeriodFramesRemainingPlayback;
ma_uint32 currentPeriodFramesRemainingCapture; ma_uint32 currentPeriodFramesRemainingCapture;
ma_uint64 lastProcessedFramePlayback; ma_uint64 lastProcessedFramePlayback;
ma_uint64 lastProcessedFrameCapture; ma_uint64 lastProcessedFrameCapture;
ma_bool32 isStarted; volatile ma_bool32 isStarted;
} null_device; } null_device;
#endif #endif
}; };
...@@ -12176,7 +12176,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame ...@@ -12176,7 +12176,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame
*pFramesWritten = 0; *pFramesWritten = 0;
} }
wasStartedOnEntry = pDevice->null_device.isStarted; wasStartedOnEntry = c89atomic_load_32(&pDevice->null_device.isStarted);
/* Keep going until everything has been read. */ /* Keep going until everything has been read. */
totalPCMFramesProcessed = 0; totalPCMFramesProcessed = 0;
...@@ -12202,7 +12202,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame ...@@ -12202,7 +12202,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame
if (pDevice->null_device.currentPeriodFramesRemainingPlayback == 0) { if (pDevice->null_device.currentPeriodFramesRemainingPlayback == 0) {
pDevice->null_device.currentPeriodFramesRemainingPlayback = 0; pDevice->null_device.currentPeriodFramesRemainingPlayback = 0;
if (!pDevice->null_device.isStarted && !wasStartedOnEntry) { if (!c89atomic_load_32(&pDevice->null_device.isStarted) && !wasStartedOnEntry) {
result = ma_device_start__null(pDevice); result = ma_device_start__null(pDevice);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
break; break;
...@@ -12222,7 +12222,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame ...@@ -12222,7 +12222,7 @@ static ma_result ma_device_write__null(ma_device* pDevice, const void* pPCMFrame
ma_uint64 currentFrame; ma_uint64 currentFrame;
/* Stop waiting if the device has been stopped. */ /* Stop waiting if the device has been stopped. */
if (!pDevice->null_device.isStarted) { if (!c89atomic_load_32(&pDevice->null_device.isStarted)) {
break; break;
} }
...@@ -12293,7 +12293,7 @@ static ma_result ma_device_read__null(ma_device* pDevice, void* pPCMFrames, ma_u ...@@ -12293,7 +12293,7 @@ static ma_result ma_device_read__null(ma_device* pDevice, void* pPCMFrames, ma_u
ma_uint64 currentFrame; ma_uint64 currentFrame;
/* Stop waiting if the device has been stopped. */ /* Stop waiting if the device has been stopped. */
if (!pDevice->null_device.isStarted) { if (!c89atomic_load_32(&pDevice->null_device.isStarted)) {
break; break;
} }
...@@ -13153,7 +13153,7 @@ typedef struct ...@@ -13153,7 +13153,7 @@ typedef struct
struct ma_completion_handler_uwp struct ma_completion_handler_uwp
{ {
ma_completion_handler_uwp_vtbl* lpVtbl; ma_completion_handler_uwp_vtbl* lpVtbl;
ma_uint32 counter; volatile ma_uint32 counter;
HANDLE hEvent; HANDLE hEvent;
}; };
...@@ -13367,7 +13367,7 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged ...@@ -13367,7 +13367,7 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged
c89atomic_exchange_32(&pThis->pDevice->wasapi.hasDefaultPlaybackDeviceChanged, MA_TRUE); c89atomic_exchange_32(&pThis->pDevice->wasapi.hasDefaultPlaybackDeviceChanged, MA_TRUE);
} }
if (dataFlow == ma_eCapture || pThis->pDevice->type == ma_device_type_loopback) { if (dataFlow == ma_eCapture || pThis->pDevice->type == ma_device_type_loopback) {
c89atomic_exchange_32(&pThis->pDevice->wasapi.hasDefaultCaptureDeviceChanged, MA_TRUE); c89atomic_exchange_32(&pThis->pDevice->wasapi.hasDefaultCaptureDeviceChanged, MA_TRUE);
} }
(void)pDefaultDeviceID; (void)pDefaultDeviceID;
...@@ -14550,7 +14550,7 @@ static ma_result ma_device_reinit__wasapi(ma_device* pDevice, ma_device_type dev ...@@ -14550,7 +14550,7 @@ static ma_result ma_device_reinit__wasapi(ma_device* pDevice, ma_device_type dev
ma_IAudioClient_GetBufferSize((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture, &pDevice->wasapi.actualPeriodSizeInFramesCapture); ma_IAudioClient_GetBufferSize((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture, &pDevice->wasapi.actualPeriodSizeInFramesCapture);
/* The device may be in a started state. If so we need to immediately restart it. */ /* The device may be in a started state. If so we need to immediately restart it. */
if (pDevice->wasapi.isStartedCapture) { if (c89atomic_load_32(&pDevice->wasapi.isStartedCapture)) {
HRESULT hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture); HRESULT hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture);
if (FAILED(hr)) { if (FAILED(hr)) {
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device after reinitialization.", ma_result_from_HRESULT(hr)); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device after reinitialization.", ma_result_from_HRESULT(hr));
...@@ -14586,7 +14586,7 @@ static ma_result ma_device_reinit__wasapi(ma_device* pDevice, ma_device_type dev ...@@ -14586,7 +14586,7 @@ static ma_result ma_device_reinit__wasapi(ma_device* pDevice, ma_device_type dev
ma_IAudioClient_GetBufferSize((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, &pDevice->wasapi.actualPeriodSizeInFramesPlayback); ma_IAudioClient_GetBufferSize((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback, &pDevice->wasapi.actualPeriodSizeInFramesPlayback);
/* The device may be in a started state. If so we need to immediately restart it. */ /* The device may be in a started state. If so we need to immediately restart it. */
if (pDevice->wasapi.isStartedPlayback) { if (c89atomic_load_32(&pDevice->wasapi.isStartedPlayback)) {
HRESULT hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback); HRESULT hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
if (FAILED(hr)) { if (FAILED(hr)) {
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device after reinitialization.", ma_result_from_HRESULT(hr)); return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device after reinitialization.", ma_result_from_HRESULT(hr));
...@@ -14849,11 +14849,11 @@ static ma_bool32 ma_device_is_reroute_required__wasapi(ma_device* pDevice, ma_de ...@@ -14849,11 +14849,11 @@ static ma_bool32 ma_device_is_reroute_required__wasapi(ma_device* pDevice, ma_de
MA_ASSERT(pDevice != NULL); MA_ASSERT(pDevice != NULL);
if (deviceType == ma_device_type_playback) { if (deviceType == ma_device_type_playback) {
return pDevice->wasapi.hasDefaultPlaybackDeviceChanged; return c89atomic_load_32(&pDevice->wasapi.hasDefaultPlaybackDeviceChanged);
} }
if (deviceType == ma_device_type_capture || deviceType == ma_device_type_loopback) { if (deviceType == ma_device_type_capture || deviceType == ma_device_type_loopback) {
return pDevice->wasapi.hasDefaultCaptureDeviceChanged; return c89atomic_load_32(&pDevice->wasapi.hasDefaultCaptureDeviceChanged);
} }
return MA_FALSE; return MA_FALSE;
...@@ -15258,7 +15258,7 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice) ...@@ -15258,7 +15258,7 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice)
mappedDeviceBufferSizeInFramesPlayback = 0; mappedDeviceBufferSizeInFramesPlayback = 0;
} }
if (!pDevice->wasapi.isStartedPlayback) { if (!c89atomic_load_32(&pDevice->wasapi.isStartedPlayback)) {
ma_uint32 startThreshold = pDevice->playback.internalPeriodSizeInFrames * 1; ma_uint32 startThreshold = pDevice->playback.internalPeriodSizeInFrames * 1;
/* Prevent a deadlock. If we don't clamp against the actual buffer size we'll never end up starting the playback device which will result in a deadlock. */ /* Prevent a deadlock. If we don't clamp against the actual buffer size we'll never end up starting the playback device which will result in a deadlock. */
...@@ -15424,7 +15424,7 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice) ...@@ -15424,7 +15424,7 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice)
} }
framesWrittenToPlaybackDevice += framesAvailablePlayback; framesWrittenToPlaybackDevice += framesAvailablePlayback;
if (!pDevice->wasapi.isStartedPlayback) { if (!c89atomic_load_32(&pDevice->wasapi.isStartedPlayback)) {
if (pDevice->playback.shareMode == ma_share_mode_exclusive || framesWrittenToPlaybackDevice >= pDevice->playback.internalPeriodSizeInFrames*1) { if (pDevice->playback.shareMode == ma_share_mode_exclusive || framesWrittenToPlaybackDevice >= pDevice->playback.internalPeriodSizeInFrames*1) {
hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback); hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
if (FAILED(hr)) { if (FAILED(hr)) {
...@@ -15472,7 +15472,7 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice) ...@@ -15472,7 +15472,7 @@ static ma_result ma_device_audio_thread__wasapi(ma_device* pDevice)
The buffer needs to be drained before stopping the device. Not doing this will result in the last few frames not getting output to The buffer needs to be drained before stopping the device. Not doing this will result in the last few frames not getting output to
the speakers. This is a problem for very short sounds because it'll result in a significant portion of it not getting played. the speakers. This is a problem for very short sounds because it'll result in a significant portion of it not getting played.
*/ */
if (pDevice->wasapi.isStartedPlayback) { if (c89atomic_load_32(&pDevice->wasapi.isStartedPlayback)) {
/* We need to make sure we put a timeout here or else we'll risk getting stuck in a deadlock in some cases. */ /* We need to make sure we put a timeout here or else we'll risk getting stuck in a deadlock in some cases. */
DWORD waitTime = pDevice->wasapi.actualPeriodSizeInFramesPlayback / pDevice->playback.internalSampleRate; DWORD waitTime = pDevice->wasapi.actualPeriodSizeInFramesPlayback / pDevice->playback.internalSampleRate;
...@@ -30701,7 +30701,7 @@ static void ma_buffer_queue_callback_capture__opensl_android(SLAndroidSimpleBuff ...@@ -30701,7 +30701,7 @@ static void ma_buffer_queue_callback_capture__opensl_android(SLAndroidSimpleBuff
*/ */
/* Don't do anything if the device is not started. */ /* Don't do anything if the device is not started. */
if (pDevice->state != MA_STATE_STARTED) { if (ma_device_get_state(pDevice) != MA_STATE_STARTED) {
return; return;
} }
...@@ -30739,7 +30739,7 @@ static void ma_buffer_queue_callback_playback__opensl_android(SLAndroidSimpleBuf ...@@ -30739,7 +30739,7 @@ static void ma_buffer_queue_callback_playback__opensl_android(SLAndroidSimpleBuf
(void)pBufferQueue; (void)pBufferQueue;
/* Don't do anything if the device is not started. */ /* Don't do anything if the device is not started. */
if (pDevice->state != MA_STATE_STARTED) { if (ma_device_get_state(pDevice) != MA_STATE_STARTED) {
return; return;
} }
...@@ -42263,13 +42263,13 @@ static MA_INLINE ma_uint32 ma_rb__extract_offset_loop_flag(ma_uint32 encodedOffs ...@@ -42263,13 +42263,13 @@ static MA_INLINE ma_uint32 ma_rb__extract_offset_loop_flag(ma_uint32 encodedOffs
static MA_INLINE void* ma_rb__get_read_ptr(ma_rb* pRB) static MA_INLINE void* ma_rb__get_read_ptr(ma_rb* pRB)
{ {
MA_ASSERT(pRB != NULL); MA_ASSERT(pRB != NULL);
return ma_offset_ptr(pRB->pBuffer, ma_rb__extract_offset_in_bytes(pRB->encodedReadOffset)); return ma_offset_ptr(pRB->pBuffer, ma_rb__extract_offset_in_bytes(c89atomic_load_32(&pRB->encodedReadOffset)));
} }
static MA_INLINE void* ma_rb__get_write_ptr(ma_rb* pRB) static MA_INLINE void* ma_rb__get_write_ptr(ma_rb* pRB)
{ {
MA_ASSERT(pRB != NULL); MA_ASSERT(pRB != NULL);
return ma_offset_ptr(pRB->pBuffer, ma_rb__extract_offset_in_bytes(pRB->encodedWriteOffset)); return ma_offset_ptr(pRB->pBuffer, ma_rb__extract_offset_in_bytes(c89atomic_load_32(&pRB->encodedWriteOffset)));
} }
static MA_INLINE ma_uint32 ma_rb__construct_offset(ma_uint32 offsetInBytes, ma_uint32 offsetLoopFlag) static MA_INLINE ma_uint32 ma_rb__construct_offset(ma_uint32 offsetInBytes, ma_uint32 offsetLoopFlag)
...@@ -42362,8 +42362,8 @@ MA_API void ma_rb_reset(ma_rb* pRB) ...@@ -42362,8 +42362,8 @@ MA_API void ma_rb_reset(ma_rb* pRB)
return; return;
} }
pRB->encodedReadOffset = 0; c89atomic_exchange_32(&pRB->encodedReadOffset, 0);
pRB->encodedWriteOffset = 0; c89atomic_exchange_32(&pRB->encodedWriteOffset, 0);
} }
MA_API ma_result ma_rb_acquire_read(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut) MA_API ma_result ma_rb_acquire_read(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut)
...@@ -42382,10 +42382,10 @@ MA_API ma_result ma_rb_acquire_read(ma_rb* pRB, size_t* pSizeInBytes, void** ppB ...@@ -42382,10 +42382,10 @@ MA_API ma_result ma_rb_acquire_read(ma_rb* pRB, size_t* pSizeInBytes, void** ppB
} }
/* The returned buffer should never move ahead of the write pointer. */ /* The returned buffer should never move ahead of the write pointer. */
writeOffset = pRB->encodedWriteOffset; writeOffset = c89atomic_load_32(&pRB->encodedWriteOffset);
ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag); ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag);
readOffset = pRB->encodedReadOffset; readOffset = c89atomic_load_32(&pRB->encodedReadOffset);
ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag); ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag);
/* /*
...@@ -42426,7 +42426,7 @@ MA_API ma_result ma_rb_commit_read(ma_rb* pRB, size_t sizeInBytes, void* pBuffer ...@@ -42426,7 +42426,7 @@ MA_API ma_result ma_rb_commit_read(ma_rb* pRB, size_t sizeInBytes, void* pBuffer
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
readOffset = pRB->encodedReadOffset; readOffset = c89atomic_load_32(&pRB->encodedReadOffset);
ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag); ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag);
/* Check that sizeInBytes is correct. It should never go beyond the end of the buffer. */ /* Check that sizeInBytes is correct. It should never go beyond the end of the buffer. */
...@@ -42462,10 +42462,10 @@ MA_API ma_result ma_rb_acquire_write(ma_rb* pRB, size_t* pSizeInBytes, void** pp ...@@ -42462,10 +42462,10 @@ MA_API ma_result ma_rb_acquire_write(ma_rb* pRB, size_t* pSizeInBytes, void** pp
} }
/* The returned buffer should never overtake the read buffer. */ /* The returned buffer should never overtake the read buffer. */
readOffset = pRB->encodedReadOffset; readOffset = c89atomic_load_32(&pRB->encodedReadOffset);
ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag); ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag);
writeOffset = pRB->encodedWriteOffset; writeOffset = c89atomic_load_32(&pRB->encodedWriteOffset);
ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag); ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag);
/* /*
...@@ -42512,7 +42512,7 @@ MA_API ma_result ma_rb_commit_write(ma_rb* pRB, size_t sizeInBytes, void* pBuffe ...@@ -42512,7 +42512,7 @@ MA_API ma_result ma_rb_commit_write(ma_rb* pRB, size_t sizeInBytes, void* pBuffe
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
writeOffset = pRB->encodedWriteOffset; writeOffset = c89atomic_load_32(&pRB->encodedWriteOffset);
ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag); ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag);
/* Check that sizeInBytes is correct. It should never go beyond the end of the buffer. */ /* Check that sizeInBytes is correct. It should never go beyond the end of the buffer. */
...@@ -42547,10 +42547,10 @@ MA_API ma_result ma_rb_seek_read(ma_rb* pRB, size_t offsetInBytes) ...@@ -42547,10 +42547,10 @@ MA_API ma_result ma_rb_seek_read(ma_rb* pRB, size_t offsetInBytes)
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
readOffset = pRB->encodedReadOffset; readOffset = c89atomic_load_32(&pRB->encodedReadOffset);
ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag); ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag);
writeOffset = pRB->encodedWriteOffset; writeOffset = c89atomic_load_32(&pRB->encodedWriteOffset);
ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag); ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag);
newReadOffsetLoopFlag = readOffsetLoopFlag; newReadOffsetLoopFlag = readOffsetLoopFlag;
...@@ -42591,10 +42591,10 @@ MA_API ma_result ma_rb_seek_write(ma_rb* pRB, size_t offsetInBytes) ...@@ -42591,10 +42591,10 @@ MA_API ma_result ma_rb_seek_write(ma_rb* pRB, size_t offsetInBytes)
return MA_INVALID_ARGS; return MA_INVALID_ARGS;
} }
readOffset = pRB->encodedReadOffset; readOffset = c89atomic_load_32(&pRB->encodedReadOffset);
ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag); ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag);
writeOffset = pRB->encodedWriteOffset; writeOffset = c89atomic_load_32(&pRB->encodedWriteOffset);
ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag); ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag);
newWriteOffsetLoopFlag = writeOffsetLoopFlag; newWriteOffsetLoopFlag = writeOffsetLoopFlag;
...@@ -42633,10 +42633,10 @@ MA_API ma_int32 ma_rb_pointer_distance(ma_rb* pRB) ...@@ -42633,10 +42633,10 @@ MA_API ma_int32 ma_rb_pointer_distance(ma_rb* pRB)
return 0; return 0;
} }
readOffset = pRB->encodedReadOffset; readOffset = c89atomic_load_32(&pRB->encodedReadOffset);
ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag); ma_rb__deconstruct_offset(readOffset, &readOffsetInBytes, &readOffsetLoopFlag);
writeOffset = pRB->encodedWriteOffset; writeOffset = c89atomic_load_32(&pRB->encodedWriteOffset);
ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag); ma_rb__deconstruct_offset(writeOffset, &writeOffsetInBytes, &writeOffsetLoopFlag);
if (readOffsetLoopFlag == writeOffsetLoopFlag) { if (readOffsetLoopFlag == writeOffsetLoopFlag) {
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