Andrew Eikum : winmm: Only start the devices thread when necessary.

Alexandre Julliard julliard at winehq.org
Mon Jan 16 13:01:33 CST 2012


Module: wine
Branch: master
Commit: 04ab858fefdd64380594c545f288df805c2d58ae
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=04ab858fefdd64380594c545f288df805c2d58ae

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Mon Jan 16 10:44:02 2012 -0600

winmm: Only start the devices thread when necessary.

---

 dlls/winmm/lolvldrv.c |    2 +-
 dlls/winmm/waveform.c |   94 ++++++++++++++++++++++++++++++++++--------------
 2 files changed, 67 insertions(+), 29 deletions(-)

diff --git a/dlls/winmm/lolvldrv.c b/dlls/winmm/lolvldrv.c
index b8f1b54..9ee0235 100644
--- a/dlls/winmm/lolvldrv.c
+++ b/dlls/winmm/lolvldrv.c
@@ -531,7 +531,7 @@ static void MMDRV_Init(void)
 
     TRACE("()\n");
 
-    init_hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+    init_hr = CoInitialize(NULL);
 
     hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
             CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&devenum);
diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c
index 383c75f..59fc0a2 100644
--- a/dlls/winmm/waveform.c
+++ b/dlls/winmm/waveform.c
@@ -464,12 +464,12 @@ static HRESULT WINMM_InitMMDevice(EDataFlow flow, IMMDevice *device,
 }
 
 static HRESULT WINMM_EnumDevices(WINMM_MMDevice **devices, UINT *devcount,
-        EDataFlow flow)
+        EDataFlow flow, IMMDeviceEnumerator *devenum)
 {
     IMMDeviceCollection *devcoll;
     HRESULT hr;
 
-    hr = IMMDeviceEnumerator_EnumAudioEndpoints(g_devenum, flow,
+    hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
             DEVICE_STATE_ACTIVE, &devcoll);
     if(FAILED(hr))
         return hr;
@@ -494,7 +494,7 @@ static HRESULT WINMM_EnumDevices(WINMM_MMDevice **devices, UINT *devcount,
         count = 0;
 
         /* make sure that device 0 is the default device */
-        hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(g_devenum,
+        hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum,
                 flow, eConsole, &def_dev);
         if(SUCCEEDED(hr)){
             WINMM_InitMMDevice(flow, def_dev, &(*devices)[0], 0);
@@ -528,27 +528,39 @@ static HRESULT WINMM_EnumDevices(WINMM_MMDevice **devices, UINT *devcount,
 
 static HRESULT WINMM_InitMMDevices(void)
 {
-    HRESULT hr;
+    HRESULT hr, init_hr;
+    IMMDeviceEnumerator *devenum = NULL;
+
+    if(g_outmmdevices_count || g_inmmdevices_count)
+        return S_FALSE;
+
+    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))
-        return hr;
+        goto exit;
 
-    hr = WINMM_EnumDevices(&g_out_mmdevices, &g_outmmdevices_count, eRender);
+    hr = WINMM_EnumDevices(&g_out_mmdevices, &g_outmmdevices_count, eRender, devenum);
     if(FAILED(hr)){
         g_outmmdevices_count = 0;
         g_inmmdevices_count = 0;
-        return hr;
+        goto exit;
     }
 
-    hr = WINMM_EnumDevices(&g_in_mmdevices, &g_inmmdevices_count, eCapture);
+    hr = WINMM_EnumDevices(&g_in_mmdevices, &g_inmmdevices_count, eCapture, devenum);
     if(FAILED(hr)){
         g_inmmdevices_count = 0;
-        return hr;
+        goto exit;
     }
 
-    return S_OK;
+exit:
+    if(devenum)
+        IMMDeviceEnumerator_Release(devenum);
+    if(SUCCEEDED(init_hr))
+        CoUninitialize();
+
+    return hr;
 }
 
 static inline BOOL WINMM_IsMapper(UINT device)
@@ -2040,10 +2052,19 @@ static DWORD WINAPI WINMM_DevicesThreadProc(void *arg)
         return 1;
     }
 
+    hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
+            CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&g_devenum);
+    if(FAILED(hr)){
+        ERR("CoCreateInstance failed: %08x\n", hr);
+        CoUninitialize();
+        return 1;
+    }
+
     g_devices_hwnd = CreateWindowW(messageW, NULL, 0, 0, 0, 0, 0,
             HWND_MESSAGE, NULL, NULL, NULL);
     if(!g_devices_hwnd){
         ERR("CreateWindow failed: %d\n", GetLastError());
+        IMMDeviceEnumerator_Release(g_devenum);
         CoUninitialize();
         return 1;
     }
@@ -2076,6 +2097,8 @@ static DWORD WINAPI WINMM_DevicesThreadProc(void *arg)
 
     DestroyWindow(g_devices_hwnd);
 
+    IMMDeviceEnumerator_Release(g_devenum);
+
     CoUninitialize();
 
     return 0;
@@ -2140,7 +2163,8 @@ static BOOL WINMM_StartDevicesThread(void)
  */
 UINT WINAPI waveOutGetNumDevs(void)
 {
-    if(!WINMM_StartDevicesThread())
+    HRESULT hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return 0;
 
     TRACE("count: %u\n", g_outmmdevices_count);
@@ -2159,9 +2183,6 @@ UINT WINAPI waveOutGetDevCapsA(UINT_PTR uDeviceID, LPWAVEOUTCAPSA lpCaps,
 
     TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);
 
-    if(!WINMM_StartDevicesThread())
-        return MMSYSERR_ERROR;
-
     if(!lpCaps)
         return MMSYSERR_INVALPARAM;
 
@@ -2189,10 +2210,12 @@ UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps,
 			       UINT uSize)
 {
     WAVEOUTCAPSW mapper_caps, *caps;
+    HRESULT hr;
 
     TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return MMSYSERR_ERROR;
 
     if (lpCaps == NULL)	return MMSYSERR_INVALPARAM;
@@ -2784,7 +2807,8 @@ UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage,
  */
 UINT WINAPI waveInGetNumDevs(void)
 {
-    if(!WINMM_StartDevicesThread())
+    HRESULT hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return 0;
 
     TRACE("count: %u\n", g_inmmdevices_count);
@@ -2798,10 +2822,12 @@ UINT WINAPI waveInGetNumDevs(void)
 UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
 {
     WAVEINCAPSW mapper_caps, *caps;
+    HRESULT hr;
 
     TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return MMSYSERR_ERROR;
 
     if(!lpCaps)
@@ -2843,9 +2869,6 @@ UINT WINAPI waveInGetDevCapsA(UINT_PTR uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSi
 
     TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);
 
-    if(!WINMM_StartDevicesThread())
-        return MMSYSERR_ERROR;
-
     if(!lpCaps)
         return MMSYSERR_INVALPARAM;
 
@@ -3155,9 +3178,12 @@ UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage,
 
 UINT WINAPI mixerGetNumDevs(void)
 {
+    HRESULT hr;
+
     TRACE("\n");
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return 0;
 
     return g_outmmdevices_count + g_inmmdevices_count;
@@ -3199,10 +3225,12 @@ UINT WINAPI mixerGetDevCapsW(UINT_PTR uDeviceID, LPMIXERCAPSW lpCaps, UINT uSize
 {
     WINMM_MMDevice *mmdevice;
     MIXERCAPSW caps;
+    HRESULT hr;
 
     TRACE("(%lu, %p, %u)\n", uDeviceID, lpCaps, uSize);
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return MMSYSERR_ERROR;
 
     if(!lpCaps)
@@ -3241,11 +3269,13 @@ UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback,
 {
     WINMM_MMDevice *mmdevice;
     MMRESULT mr;
+    HRESULT hr;
 
     TRACE("(%p, %d, %lx, %lx, %x)\n", lphMix, uDeviceID, dwCallback,
             dwInstance, fdwOpen);
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return MMSYSERR_ERROR;
 
     if(!lphMix)
@@ -3289,10 +3319,12 @@ UINT WINAPI mixerClose(HMIXER hMix)
 UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
 {
     WINMM_MMDevice *mmdevice;
+    HRESULT hr;
 
     TRACE("(%p, %p, %x)\n", hmix, lpid, fdwID);
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return MMSYSERR_ERROR;
 
     if(!lpid)
@@ -3315,10 +3347,12 @@ UINT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdW
 				    DWORD fdwDetails)
 {
     WINMM_ControlDetails details;
+    HRESULT hr;
 
     TRACE("(%p, %p, %x)\n", hmix, lpmcdW, fdwDetails);
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return MMSYSERR_ERROR;
 
     if(!lpmcdW)
@@ -3500,10 +3534,12 @@ UINT WINAPI mixerGetLineControlsW(HMIXEROBJ hmix, LPMIXERLINECONTROLSW lpmlcW,
 				  DWORD fdwControls)
 {
     WINMM_MMDevice *mmdevice;
+    HRESULT hr;
 
     TRACE("(%p, %p, %08x)\n", hmix, lpmlcW, fdwControls);
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return MMSYSERR_ERROR;
 
     if(fdwControls & ~(MIXER_GETLINECONTROLSF_ALL |
@@ -3716,10 +3752,12 @@ UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW, DWORD fdwInfo
 {
     UINT mmdev_index;
     WINMM_MMDevice *mmdevice;
+    HRESULT hr;
 
     TRACE("(%p, %p, %x)\n", hmix, lpmliW, fdwInfo);
 
-    if(!WINMM_StartDevicesThread())
+    hr = WINMM_InitMMDevices();
+    if(FAILED(hr))
         return MMSYSERR_ERROR;
 
     if(!lpmliW || lpmliW->cbStruct < sizeof(MIXERLINEW))




More information about the wine-cvs mailing list