refactored COM initialization for dsound, asio and wasapi to new source file pa_win_coinitialize.c. fixes com uninitialisation bugs in error cases. resolves ticket #128
This commit is contained in:
parent
cbd24dc45c
commit
52ab9d6600
5 changed files with 301 additions and 90 deletions
|
|
@ -75,6 +75,8 @@
|
|||
#include "pa_debugprint.h"
|
||||
#include "pa_ringbuffer.h"
|
||||
|
||||
#include "pa_win_coinitialize.h"
|
||||
|
||||
#ifndef NTDDI_VERSION
|
||||
|
||||
#undef WINVER
|
||||
|
|
@ -370,6 +372,8 @@ typedef struct
|
|||
|
||||
/* implementation specific data goes here */
|
||||
|
||||
PaWinUtilComInitializationResult comInitializationResult;
|
||||
|
||||
//in case we later need the synch
|
||||
IMMDeviceEnumerator *enumerator;
|
||||
|
||||
|
|
@ -512,8 +516,6 @@ void *PaWasapi_ReallocateMemory(void *ptr, size_t size);
|
|||
void PaWasapi_FreeMemory(void *ptr);
|
||||
|
||||
// Local statics
|
||||
static volatile BOOL g_WasapiCOMInit = FALSE;
|
||||
static volatile DWORD g_WasapiInitThread = 0;
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#define LogHostError(HRES) __LogHostError(HRES, __FUNCTION__, __FILE__, __LINE__)
|
||||
|
|
@ -1057,26 +1059,6 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
return paNoError;
|
||||
}
|
||||
|
||||
/*
|
||||
If COM is already initialized CoInitialize will either return
|
||||
FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different
|
||||
threading mode. In either case we shouldn't consider it an error
|
||||
but we need to be careful to not call CoUninitialize() if
|
||||
RPC_E_CHANGED_MODE was returned.
|
||||
*/
|
||||
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
if (FAILED(hr) && (hr != RPC_E_CHANGED_MODE))
|
||||
{
|
||||
PRINT(("WASAPI: failed CoInitialize"));
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
if (hr != RPC_E_CHANGED_MODE)
|
||||
g_WasapiCOMInit = TRUE;
|
||||
|
||||
// Memorize calling thread id and report warning on Uninitialize if calling thread is different
|
||||
// as CoInitialize must match CoUninitialize in the same thread.
|
||||
g_WasapiInitThread = GetCurrentThreadId();
|
||||
|
||||
paWasapi = (PaWasapiHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaWasapiHostApiRepresentation) );
|
||||
if (paWasapi == NULL)
|
||||
{
|
||||
|
|
@ -1084,6 +1066,12 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
goto error;
|
||||
}
|
||||
|
||||
result = PaWinUtil_CoInitialize( paWASAPI, &paWasapi->comInitializationResult );
|
||||
if( result != paNoError )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
paWasapi->allocations = PaUtil_CreateAllocationGroup();
|
||||
if (paWasapi->allocations == NULL)
|
||||
{
|
||||
|
|
@ -1454,26 +1442,12 @@ static void Terminate( PaUtilHostApiRepresentation *hostApi )
|
|||
PaUtil_DestroyAllocationGroup(paWasapi->allocations);
|
||||
}
|
||||
|
||||
PaWinUtil_CoUninitialize( paWASAPI, &paWasapi->comInitializationResult );
|
||||
|
||||
PaUtil_FreeMemory(paWasapi);
|
||||
|
||||
// Close AVRT
|
||||
CloseAVRT();
|
||||
|
||||
// Uninit COM (checking calling thread we won't unitialize user's COM if one is calling
|
||||
// Pa_Unitialize by mistake from not initializing thread)
|
||||
if (g_WasapiCOMInit)
|
||||
{
|
||||
DWORD calling_thread_id = GetCurrentThreadId();
|
||||
if (g_WasapiInitThread != calling_thread_id)
|
||||
{
|
||||
PRINT(("WASAPI: failed CoUninitializes calling thread[%d] does not match initializing thread[%d]\n",
|
||||
calling_thread_id, g_WasapiInitThread));
|
||||
}
|
||||
else
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue