static void _FinishStream(PaWasapiStream *stream);\r
\r
// Local statics\r
-static volatile BOOL g_bCOMInitialized = FALSE;\r
+static volatile BOOL g_WasapiCOMInit = FALSE;\r
+static volatile DWORD g_WasapiInitThread = 0;\r
\r
// ------------------------------------------------------------------------------------------\r
#define LogHostError(HRES) __LogHostError(HRES, __FUNCTION__, __FILE__, __LINE__)\r
return paUnanticipatedHostError;\r
}\r
if (hr != RPC_E_CHANGED_MODE)\r
- g_bCOMInitialized = TRUE;\r
+ g_WasapiCOMInit = TRUE;\r
+\r
+ // Memorize calling thread id and report warning on Uninitialize if calling thread is different\r
+ // as CoInitialize must match CoUninitialize in the same thread.\r
+ g_WasapiInitThread = GetCurrentThreadId();\r
\r
paWasapi = (PaWasapiHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaWasapiHostApiRepresentation) );\r
if (paWasapi == NULL)\r
// Close AVRT\r
CloseAVRT();\r
\r
- // Uninit COM\r
- if (g_bCOMInitialized)\r
- CoUninitialize();\r
+ // Uninit COM (checking calling thread we won't unitialize user's COM if one is calling\r
+ // Pa_Unitialize by mistake from not initializing thread)\r
+ if (g_WasapiCOMInit)\r
+ {\r
+ DWORD calling_thread_id = GetCurrentThreadId();\r
+ if (g_WasapiInitThread != calling_thread_id)\r
+ {\r
+ PRINT(("WASAPI: failed CoUninitializes calling thread[%d] does not match initializing thread[%d]\n", \r
+ calling_thread_id, g_WasapiInitThread));\r
+ }\r
+ else\r
+ {\r
+ CoUninitialize();\r
+ }\r
+ }\r
}\r
\r
// ------------------------------------------------------------------------------------------\r