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