[PATCH v2 5/6] winecoreaudio: Use the global lock to protect the audio client.

Andrew Eikum aeikum at codeweavers.com
Wed Nov 17 09:10:16 CST 2021


From: Huw Davies <huw at codeweavers.com>

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/winecoreaudio.drv/mmdevdrv.c | 115 +++++++++++++++---------------
 1 file changed, 59 insertions(+), 56 deletions(-)

diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index e82962db1ba..ebab18df75b 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -1234,16 +1234,19 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
         }
     }
 
-    OSSpinLockLock(&This->stream->lock);
+    EnterCriticalSection(&g_sessions_lock);
 
     if(This->initted){
-        OSSpinLockUnlock(&This->stream->lock);
+        LeaveCriticalSection(&g_sessions_lock);
         return AUDCLNT_E_ALREADY_INITIALIZED;
     }
 
+    OSSpinLockLock(&This->stream->lock);
+
     This->stream->fmt = clone_format(fmt);
     if(!This->stream->fmt){
         OSSpinLockUnlock(&This->stream->lock);
+        LeaveCriticalSection(&g_sessions_lock);
         return E_OUTOFMEMORY;
     }
 
@@ -1259,6 +1262,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
         CoTaskMemFree(This->stream->fmt);
         This->stream->fmt = NULL;
         OSSpinLockUnlock(&This->stream->lock);
+        LeaveCriticalSection(&g_sessions_lock);
         return hr;
     }
 
@@ -1278,6 +1282,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
             CoTaskMemFree(This->stream->fmt);
             This->stream->fmt = NULL;
             OSSpinLockUnlock(&This->stream->lock);
+            LeaveCriticalSection(&g_sessions_lock);
             return osstatus_to_hresult(sc);
         }
     }else{
@@ -1294,6 +1299,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
             CoTaskMemFree(This->stream->fmt);
             This->stream->fmt = NULL;
             OSSpinLockUnlock(&This->stream->lock);
+            LeaveCriticalSection(&g_sessions_lock);
             return osstatus_to_hresult(sc);
         }
     }
@@ -1308,6 +1314,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
         CoTaskMemFree(This->stream->fmt);
         This->stream->fmt = NULL;
         OSSpinLockUnlock(&This->stream->lock);
+        LeaveCriticalSection(&g_sessions_lock);
         return osstatus_to_hresult(sc);
     }
 
@@ -1323,6 +1330,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
         CoTaskMemFree(This->stream->fmt);
         This->stream->fmt = NULL;
         OSSpinLockUnlock(&This->stream->lock);
+        LeaveCriticalSection(&g_sessions_lock);
         return osstatus_to_hresult(sc);
     }
 
@@ -1339,6 +1347,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
         CoTaskMemFree(This->stream->fmt);
         This->stream->fmt = NULL;
         OSSpinLockUnlock(&This->stream->lock);
+        LeaveCriticalSection(&g_sessions_lock);
         return E_OUTOFMEMORY;
     }
 
@@ -1348,29 +1357,26 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
     This->stream->share = mode;
     This->flags = flags;
 
-    EnterCriticalSection(&g_sessions_lock);
-
     hr = get_audio_session(sessionguid, This->parent, fmt->nChannels,
             &This->session);
     if(FAILED(hr)){
-        LeaveCriticalSection(&g_sessions_lock);
         CoTaskMemFree(This->stream->fmt);
         This->stream->fmt = NULL;
         HeapFree(GetProcessHeap(), 0, This->vols);
         This->vols = NULL;
         OSSpinLockUnlock(&This->stream->lock);
+        LeaveCriticalSection(&g_sessions_lock);
         return E_INVALIDARG;
     }
 
     list_add_tail(&This->session->clients, &This->entry);
 
-    LeaveCriticalSection(&g_sessions_lock);
-
     ca_setvol(This, -1);
 
     This->initted = TRUE;
 
     OSSpinLockUnlock(&This->stream->lock);
+    LeaveCriticalSection(&g_sessions_lock);
 
     return S_OK;
 }
@@ -1983,41 +1989,35 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
         HANDLE event)
 {
     ACImpl *This = impl_from_IAudioClient3(iface);
+    HRESULT hr = S_OK;
 
     TRACE("(%p)->(%p)\n", This, event);
 
     if(!event)
         return E_INVALIDARG;
 
-    OSSpinLockLock(&This->stream->lock);
+    EnterCriticalSection(&g_sessions_lock);
 
-    if(!This->initted){
-        OSSpinLockUnlock(&This->stream->lock);
-        return AUDCLNT_E_NOT_INITIALIZED;
-    }
-
-    if(!(This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK)){
-        OSSpinLockUnlock(&This->stream->lock);
-        return AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED;
-    }
-
-    if (This->event){
-        OSSpinLockUnlock(&This->stream->lock);
+    if(!This->initted)
+        hr = AUDCLNT_E_NOT_INITIALIZED;
+    else if(!(This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
+        hr = AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED;
+    else if(This->event){
         FIXME("called twice\n");
-        return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
-    }
+        hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
+    }else
+        This->event = event;
 
-    This->event = event;
+    LeaveCriticalSection(&g_sessions_lock);
 
-    OSSpinLockUnlock(&This->stream->lock);
-
-    return S_OK;
+    return hr;
 }
 
 static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
         void **ppv)
 {
     ACImpl *This = impl_from_IAudioClient3(iface);
+    HRESULT hr;
 
     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
 
@@ -2025,24 +2025,24 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
         return E_POINTER;
     *ppv = NULL;
 
-    OSSpinLockLock(&This->stream->lock);
+    EnterCriticalSection(&g_sessions_lock);
 
     if(!This->initted){
-        OSSpinLockUnlock(&This->stream->lock);
-        return AUDCLNT_E_NOT_INITIALIZED;
+        hr = AUDCLNT_E_NOT_INITIALIZED;
+        goto end;
     }
 
     if(IsEqualIID(riid, &IID_IAudioRenderClient)){
         if(This->dataflow != eRender){
-            OSSpinLockUnlock(&This->stream->lock);
-            return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
+            hr = AUDCLNT_E_WRONG_ENDPOINT_TYPE;
+            goto end;
         }
         IAudioRenderClient_AddRef(&This->IAudioRenderClient_iface);
         *ppv = &This->IAudioRenderClient_iface;
     }else if(IsEqualIID(riid, &IID_IAudioCaptureClient)){
         if(This->dataflow != eCapture){
-            OSSpinLockUnlock(&This->stream->lock);
-            return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
+            hr = AUDCLNT_E_WRONG_ENDPOINT_TYPE;
+            goto end;
         }
         IAudioCaptureClient_AddRef(&This->IAudioCaptureClient_iface);
         *ppv = &This->IAudioCaptureClient_iface;
@@ -2056,8 +2056,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
         if(!This->session_wrapper){
             This->session_wrapper = AudioSessionWrapper_Create(This);
             if(!This->session_wrapper){
-                OSSpinLockUnlock(&This->stream->lock);
-                return E_OUTOFMEMORY;
+                hr = E_OUTOFMEMORY;
+                goto end;
             }
         }else
             IAudioSessionControl2_AddRef(&This->session_wrapper->IAudioSessionControl2_iface);
@@ -2067,8 +2067,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
         if(!This->session_wrapper){
             This->session_wrapper = AudioSessionWrapper_Create(This);
             if(!This->session_wrapper){
-                OSSpinLockUnlock(&This->stream->lock);
-                return E_OUTOFMEMORY;
+                hr = E_OUTOFMEMORY;
+                goto end;
             }
         }else
             IChannelAudioVolume_AddRef(&This->session_wrapper->IChannelAudioVolume_iface);
@@ -2078,8 +2078,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
         if(!This->session_wrapper){
             This->session_wrapper = AudioSessionWrapper_Create(This);
             if(!This->session_wrapper){
-                OSSpinLockUnlock(&This->stream->lock);
-                return E_OUTOFMEMORY;
+                hr = E_OUTOFMEMORY;
+                goto end;
             }
         }else
             ISimpleAudioVolume_AddRef(&This->session_wrapper->ISimpleAudioVolume_iface);
@@ -2087,15 +2087,15 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
         *ppv = &This->session_wrapper->ISimpleAudioVolume_iface;
     }
 
-    if(*ppv){
-        OSSpinLockUnlock(&This->stream->lock);
-        return S_OK;
+    if(*ppv) hr = S_OK;
+    else{
+        return E_NOINTERFACE;
+        FIXME("stub %s\n", debugstr_guid(riid));
     }
 
-    OSSpinLockUnlock(&This->stream->lock);
-
-    FIXME("stub %s\n", debugstr_guid(riid));
-    return E_NOINTERFACE;
+end:
+    LeaveCriticalSection(&g_sessions_lock);
+    return hr;
 }
 
 static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface,
@@ -2749,17 +2749,20 @@ static ULONG WINAPI AudioSessionControl_Release(IAudioSessionControl2 *iface)
 {
     AudioSessionWrapper *This = impl_from_IAudioSessionControl2(iface);
     ULONG ref;
+
+    EnterCriticalSection(&g_sessions_lock);
+
     ref = InterlockedDecrement(&This->ref);
     TRACE("(%p) Refcount now %u\n", This, ref);
     if(!ref){
         if(This->client){
-            OSSpinLockLock(&This->client->stream->lock);
             This->client->session_wrapper = NULL;
-            OSSpinLockUnlock(&This->client->stream->lock);
             AudioClient_Release(&This->client->IAudioClient3_iface);
         }
         HeapFree(GetProcessHeap(), 0, This);
     }
+
+    LeaveCriticalSection(&g_sessions_lock);
     return ref;
 }
 
@@ -3189,14 +3192,14 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
     if(index >= This->stream->fmt->nChannels)
         return E_INVALIDARG;
 
-    OSSpinLockLock(&This->stream->lock);
+    EnterCriticalSection(&g_sessions_lock);
 
     This->vols[index] = level;
 
     WARN("CoreAudio doesn't support per-channel volume control\n");
     ret = ca_setvol(This, index);
 
-    OSSpinLockUnlock(&This->stream->lock);
+    LeaveCriticalSection(&g_sessions_lock);
 
     return ret;
 }
@@ -3223,7 +3226,7 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
         IAudioStreamVolume *iface, UINT32 count, const float *levels)
 {
     ACImpl *This = impl_from_IAudioStreamVolume(iface);
-    int i;
+    UINT32 i;
     HRESULT ret;
 
     TRACE("(%p)->(%d, %p)\n", This, count, levels);
@@ -3234,14 +3237,14 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
     if(count != This->stream->fmt->nChannels)
         return E_INVALIDARG;
 
-    OSSpinLockLock(&This->stream->lock);
+    EnterCriticalSection(&g_sessions_lock);
 
     for(i = 0; i < count; ++i)
         This->vols[i] = levels[i];
 
     ret = ca_setvol(This, -1);
 
-    OSSpinLockUnlock(&This->stream->lock);
+    LeaveCriticalSection(&g_sessions_lock);
 
     return ret;
 }
@@ -3250,7 +3253,7 @@ static HRESULT WINAPI AudioStreamVolume_GetAllVolumes(
         IAudioStreamVolume *iface, UINT32 count, float *levels)
 {
     ACImpl *This = impl_from_IAudioStreamVolume(iface);
-    int i;
+    UINT32 i;
 
     TRACE("(%p)->(%d, %p)\n", This, count, levels);
 
@@ -3260,12 +3263,12 @@ static HRESULT WINAPI AudioStreamVolume_GetAllVolumes(
     if(count != This->stream->fmt->nChannels)
         return E_INVALIDARG;
 
-    OSSpinLockLock(&This->stream->lock);
+    EnterCriticalSection(&g_sessions_lock);
 
     for(i = 0; i < count; ++i)
         levels[i] = This->vols[i];
 
-    OSSpinLockUnlock(&This->stream->lock);
+    LeaveCriticalSection(&g_sessions_lock);
 
     return S_OK;
 }
-- 
2.33.1





More information about the wine-devel mailing list