Andrew Eikum : dsound: Don' t launch a separate thread for the mmdevapi enumerator.
Alexandre Julliard
julliard at winehq.org
Mon Jan 16 13:01:33 CST 2012
Module: wine
Branch: master
Commit: 6d391df4aaefaef1e13ff2dd3571f96fdff6405d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6d391df4aaefaef1e13ff2dd3571f96fdff6405d
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Mon Jan 16 10:44:38 2012 -0600
dsound: Don't launch a separate thread for the mmdevapi enumerator.
---
dlls/dsound/dsound_main.c | 133 +++++++++++++++------------------------------
1 files changed, 43 insertions(+), 90 deletions(-)
diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c
index cc9f44c..c0d2b33 100644
--- a/dlls/dsound/dsound_main.c
+++ b/dlls/dsound/dsound_main.c
@@ -88,17 +88,6 @@ CRITICAL_SECTION DSOUND_capturers_lock = { &DSOUND_capturers_lock_debug, -1, 0,
GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
-static IMMDeviceEnumerator *g_devenum;
-static CRITICAL_SECTION g_devenum_lock;
-static CRITICAL_SECTION_DEBUG g_devenum_lock_debug =
-{
- 0, 0, &g_devenum_lock,
- { &g_devenum_lock_debug.ProcessLocksList, &g_devenum_lock_debug.ProcessLocksList },
- 0, 0, { (DWORD_PTR)(__FILE__ ": g_devenum_lock") }
-};
-static CRITICAL_SECTION g_devenum_lock = { &g_devenum_lock_debug, -1, 0, 0, 0, 0 };
-static HANDLE g_devenum_thread;
-
WCHAR wine_vxd_drv[] = { 'w','i','n','e','m','m','.','v','x','d', 0 };
/* All default settings, you most likely don't want to touch these, see wiki on UsefulRegistryKeys */
@@ -190,83 +179,29 @@ static const char * get_device_id(LPCGUID pGuid)
return debugstr_guid(pGuid);
}
-/* The MMDeviceEnumerator object has to be created & destroyed
- * from the same thread. */
-static DWORD WINAPI devenum_thread_proc(void *arg)
+static HRESULT get_mmdevenum(IMMDeviceEnumerator **devenum)
{
- HANDLE evt = arg;
- HRESULT hr;
- MSG msg;
+ HRESULT hr, init_hr;
- hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if(FAILED(hr)){
- ERR("CoInitializeEx failed: %08x\n", hr);
- return 1;
- }
+ init_hr = CoInitialize(NULL);
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
- CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&g_devenum);
+ CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)devenum);
if(FAILED(hr)){
- ERR("CoCreateInstance failed: %08x\n", hr);
CoUninitialize();
- return 1;
- }
-
- SetEvent(evt);
-
- PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
-
- while(GetMessageW(&msg, NULL, 0, 0)){
- if(msg.hwnd)
- DispatchMessageW(&msg);
- else
- ERR("Unknown message: %04x\n", msg.message);
+ *devenum = NULL;
+ ERR("CoCreateInstance failed: %08x\n", hr);
+ return hr;
}
- IMMDeviceEnumerator_Release(g_devenum);
- g_devenum = NULL;
- CoUninitialize();
-
- return 0;
+ return init_hr;
}
-static IMMDeviceEnumerator *get_mmdevenum(void)
+static void release_mmdevenum(IMMDeviceEnumerator *devenum, HRESULT init_hr)
{
- HANDLE events[2];
- DWORD wait;
-
- EnterCriticalSection(&g_devenum_lock);
-
- if(g_devenum){
- LeaveCriticalSection(&g_devenum_lock);
- return g_devenum;
- }
-
- events[0] = CreateEventW(NULL, FALSE, FALSE, NULL);
-
- g_devenum_thread = CreateThread(NULL, 0, devenum_thread_proc,
- events[0], 0, NULL);
- if(!g_devenum_thread){
- LeaveCriticalSection(&g_devenum_lock);
- CloseHandle(events[0]);
- return NULL;
- }
-
- events[1] = g_devenum_thread;
- wait = WaitForMultipleObjects(2, events, FALSE, INFINITE);
- CloseHandle(events[0]);
- if(wait != WAIT_OBJECT_0){
- if(wait == 1 + WAIT_OBJECT_0){
- CloseHandle(g_devenum_thread);
- g_devenum_thread = NULL;
- }
- LeaveCriticalSection(&g_devenum_lock);
- return NULL;
- }
-
- LeaveCriticalSection(&g_devenum_lock);
-
- return g_devenum;
+ IMMDeviceEnumerator_Release(devenum);
+ if(SUCCEEDED(init_hr))
+ CoUninitialize();
}
static HRESULT get_mmdevice_guid(IMMDevice *device, IPropertyStore *ps,
@@ -326,16 +261,16 @@ HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
IMMDeviceEnumerator *devenum;
EDataFlow flow = (EDataFlow)-1;
ERole role = (ERole)-1;
- HRESULT hr;
+ HRESULT hr, init_hr;
TRACE("(%s,%p)\n", get_device_id(pGuidSrc),pGuidDest);
if(!pGuidSrc || !pGuidDest)
return DSERR_INVALIDPARAM;
- devenum = get_mmdevenum();
+ init_hr = get_mmdevenum(&devenum);
if(!devenum)
- return DSERR_GENERIC;
+ return init_hr;
if(IsEqualGUID(&DSDEVID_DefaultPlayback, pGuidSrc)){
role = eMultimedia;
@@ -358,15 +293,20 @@ HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
flow, role, &device);
if(FAILED(hr)){
WARN("GetDefaultAudioEndpoint failed: %08x\n", hr);
+ release_mmdevenum(devenum, init_hr);
return DSERR_NODRIVER;
}
hr = get_mmdevice_guid(device, NULL, pGuidDest);
IMMDevice_Release(device);
+ release_mmdevenum(devenum, init_hr);
+
return (hr == S_OK) ? DS_OK : hr;
}
+ release_mmdevenum(devenum, init_hr);
+
*pGuidDest = *pGuidSrc;
return DS_OK;
@@ -424,22 +364,24 @@ HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device)
IMMDeviceEnumerator *devenum;
IMMDeviceCollection *coll;
UINT count, i;
- HRESULT hr;
+ HRESULT hr, init_hr;
- devenum = get_mmdevenum();
+ init_hr = get_mmdevenum(&devenum);
if(!devenum)
- return DSERR_GENERIC;
+ return init_hr;
hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
DEVICE_STATE_ACTIVE, &coll);
if(FAILED(hr)){
WARN("EnumAudioEndpoints failed: %08x\n", hr);
+ release_mmdevenum(devenum, init_hr);
return hr;
}
hr = IMMDeviceCollection_GetCount(coll, &count);
if(FAILED(hr)){
IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
WARN("GetCount failed: %08x\n", hr);
return hr;
}
@@ -457,14 +399,20 @@ HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device)
continue;
}
- if(IsEqualGUID(&guid, tgt))
+ if(IsEqualGUID(&guid, tgt)){
+ IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
return DS_OK;
+ }
IMMDevice_Release(*device);
}
WARN("No device with GUID %s found!\n", wine_dbgstr_guid(tgt));
+ IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
+
return DSERR_INVALIDPARAM;
}
@@ -519,19 +467,20 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
IMMDevice *defdev = NULL;
UINT count, i, n;
BOOL keep_going;
- HRESULT hr;
+ HRESULT hr, init_hr;
static const WCHAR primary_desc[] = {'P','r','i','m','a','r','y',' ',
'S','o','u','n','d',' ','D','r','i','v','e','r',0};
static const WCHAR empty_drv[] = {0};
- devenum = get_mmdevenum();
+ init_hr = get_mmdevenum(&devenum);
if(!devenum)
- return DS_OK;
+ return init_hr;
- hr = IMMDeviceEnumerator_EnumAudioEndpoints(g_devenum, flow,
+ hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
DEVICE_STATE_ACTIVE, &coll);
if(FAILED(hr)){
+ release_mmdevenum(devenum, init_hr);
WARN("EnumAudioEndpoints failed: %08x\n", hr);
return DS_OK;
}
@@ -539,12 +488,15 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
hr = IMMDeviceCollection_GetCount(coll, &count);
if(FAILED(hr)){
IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
WARN("GetCount failed: %08x\n", hr);
return DS_OK;
}
- if(count == 0)
+ if(count == 0){
+ release_mmdevenum(devenum, init_hr);
return DS_OK;
+ }
TRACE("Calling back with NULL (%s)\n", wine_dbgstr_w(primary_desc));
keep_going = cb(NULL, primary_desc, empty_drv, user);
@@ -583,6 +535,8 @@ HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
IMMDevice_Release(defdev);
IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
+
return (keep_going == TRUE) ? S_OK : S_FALSE;
}
@@ -862,7 +816,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
TRACE("DLL_PROCESS_DETACH\n");
DeleteCriticalSection(&DSOUND_renderers_lock);
DeleteCriticalSection(&DSOUND_capturers_lock);
- DeleteCriticalSection(&g_devenum_lock);
break;
default:
TRACE("UNKNOWN REASON\n");
More information about the wine-cvs
mailing list