From 0f612cc4fb372a5ebaab78ad432a1259044dff4c Mon Sep 17 00:00:00 2001 From: Etienne Dechamps Date: Sun, 2 Jun 2024 16:06:55 +0100 Subject: [PATCH] Wait for the DS thread when stopping The previous code would return from Pa_StopStream() when the streaming thread signals that it is done. This is racy, because the streaming thread is technically still running code by that point. If, for example, the PortAudio user decides to unload the entire PortAudio DLL as soon as Pa_StopStream() returns, hilarity could ensue. Instead we can simply wait on the thread handle itself, which is both safer and simpler. --- src/hostapi/dsound/pa_win_ds.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/src/hostapi/dsound/pa_win_ds.c b/src/hostapi/dsound/pa_win_ds.c index c88ad62d8..9c7328ac9 100644 --- a/src/hostapi/dsound/pa_win_ds.c +++ b/src/hostapi/dsound/pa_win_ds.c @@ -316,7 +316,6 @@ typedef struct PaWinDsStream #endif HANDLE processingThread; PA_THREAD_ID processingThreadId; - HANDLE processingThreadCompleted; #endif } PaWinDsStream; @@ -2090,16 +2089,6 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, } #endif -#ifndef PA_WIN_DS_USE_WMME_TIMER - stream->processingThreadCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL ); - if( stream->processingThreadCompleted == NULL ) - { - result = paUnanticipatedHostError; - PA_DS_SET_LAST_DIRECTSOUND_ERROR( GetLastError() ); - goto error; - } -#endif - /* set up i/o parameters */ if( userRequestedHostInputBufferSizeFrames > 0 || userRequestedHostOutputBufferSizeFrames > 0 ) @@ -2292,11 +2281,6 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, CloseHandle( stream->waitableTimer ); #endif -#ifndef PA_WIN_DS_USE_WMME_TIMER - if( stream->processingThreadCompleted != NULL ) - CloseHandle( stream->processingThreadCompleted ); -#endif - if( stream->pDirectSoundOutputBuffer ) { IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer ); @@ -2783,8 +2767,6 @@ PA_THREAD_FUNC ProcessingThreadProc( void *pArg ) } #endif /* PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT */ - SetEvent( stream->processingThreadCompleted ); - return 0; } @@ -2806,10 +2788,6 @@ static PaError CloseStream( PaStream* s ) CloseHandle( stream->waitableTimer ); #endif -#ifndef PA_WIN_DS_USE_WMME_TIMER - CloseHandle( stream->processingThreadCompleted ); -#endif - // Cleanup the sound buffers if( stream->pDirectSoundOutputBuffer ) { @@ -2904,10 +2882,6 @@ static PaError StartStream( PaStream *s ) ResetEvent( stream->processingCompleted ); -#ifndef PA_WIN_DS_USE_WMME_TIMER - ResetEvent( stream->processingThreadCompleted ); -#endif - if( stream->bufferProcessor.inputChannelCount > 0 ) { // Start the buffer capture @@ -3085,7 +3059,7 @@ static PaError StopStream( PaStream *s ) #else if( stream->processingThread ) { - if( WaitForSingleObject( stream->processingThreadCompleted, 30*100 ) == WAIT_TIMEOUT ) + if( WaitForSingleObject( stream->processingThread, 30*100 ) == WAIT_TIMEOUT ) return paUnanticipatedHostError; CloseHandle( stream->processingThread ); /* Delete thread. */