Andrew Eikum : winmm: Perform Open and Close callbacks from client thread.

Alexandre Julliard julliard at winehq.org
Mon Jul 18 12:47:02 CDT 2011


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

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Mon Jul 18 11:19:35 2011 -0500

winmm: Perform Open and Close callbacks from client thread.

---

 dlls/winmm/tests/wave.c |    5 +++
 dlls/winmm/waveform.c   |   64 +++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/dlls/winmm/tests/wave.c b/dlls/winmm/tests/wave.c
index 5bf7753..921216b 100644
--- a/dlls/winmm/tests/wave.c
+++ b/dlls/winmm/tests/wave.c
@@ -37,6 +37,8 @@
 
 #include "winmm_test.h"
 
+static DWORD g_tid;
+
 static void test_multiple_waveopens(void)
 {
     HWAVEOUT handle1, handle2;
@@ -559,6 +561,8 @@ static void CALLBACK callback_func(HWAVEOUT hwo, UINT uMsg,
                                    DWORD_PTR dwInstance,
                                    DWORD dwParam1, DWORD dwParam2)
 {
+    if(uMsg == WOM_OPEN || uMsg == WOM_CLOSE)
+        ok(GetCurrentThreadId() == g_tid, "Got different thread ID\n");
     SetEvent((HANDLE)dwInstance);
 }
 
@@ -648,6 +652,7 @@ static void wave_out_test_deviceOut(int device, double duration,
         return;
     }
     wout=NULL;
+    g_tid = GetCurrentThreadId();
     rc=waveOutOpen(&wout,device,pwfx,callback,callback_instance,flags);
     /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
     /* It is acceptable to fail on formats that are not specified to work */
diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c
index 5121bb7..a06d12f 100644
--- a/dlls/winmm/waveform.c
+++ b/dlls/winmm/waveform.c
@@ -998,8 +998,6 @@ static LRESULT WOD_Open(WINMM_OpenInfo *info)
 
     LeaveCriticalSection(&device->lock);
 
-    WINMM_NotifyClient(&cb_info, WOM_OPEN, 0, 0);
-
     return MMSYSERR_NOERROR;
 
 error:
@@ -1069,8 +1067,6 @@ static LRESULT WID_Open(WINMM_OpenInfo *info)
 
     LeaveCriticalSection(&device->lock);
 
-    WINMM_NotifyClient(&cb_info, WIM_OPEN, 0, 0);
-
     return MMSYSERR_NOERROR;
 
 error:
@@ -1143,8 +1139,6 @@ static LRESULT WOD_Close(HWAVEOUT hwave)
 
     LeaveCriticalSection(&device->lock);
 
-    WINMM_NotifyClient(&cb_info, WOM_CLOSE, 0, 0);
-
     return MMSYSERR_NOERROR;
 }
 
@@ -1167,8 +1161,6 @@ static LRESULT WID_Close(HWAVEIN hwave)
 
     LeaveCriticalSection(&device->lock);
 
-    WINMM_NotifyClient(&cb_info, WIM_CLOSE, 0, 0);
-
     return MMSYSERR_NOERROR;
 }
 
@@ -2325,6 +2317,7 @@ MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID,
     LRESULT res;
     HRESULT hr;
     WINMM_OpenInfo info;
+    WINMM_CBInfo cb_info;
 
     TRACE("(%p, %u, %p, %lx, %lx, %08x)\n", lphWaveOut, uDeviceID, lpFormat,
             dwCallback, dwInstance, dwFlags);
@@ -2354,6 +2347,13 @@ MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID,
     if(lphWaveOut)
         *lphWaveOut = (HWAVEOUT)info.handle;
 
+    cb_info.flags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+    cb_info.callback = dwCallback;
+    cb_info.user = dwInstance;
+    cb_info.hwave = info.handle;
+
+    WINMM_NotifyClient(&cb_info, WOM_OPEN, 0, 0);
+
     return res;
 }
 
@@ -2362,12 +2362,30 @@ MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID,
  */
 UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
 {
+    UINT res;
+    WINMM_Device *device;
+    WINMM_CBInfo cb_info;
+
     TRACE("(%p)\n", hWaveOut);
 
     if(!WINMM_StartDevicesThread())
         return MMSYSERR_ERROR;
 
-    return SendMessageW(g_devices_hwnd, WODM_CLOSE, (WPARAM)hWaveOut, 0);
+    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveOut);
+
+    if(!WINMM_ValidateAndLock(device))
+        return MMSYSERR_INVALHANDLE;
+
+    memcpy(&cb_info, &device->cb_info, sizeof(cb_info));
+
+    LeaveCriticalSection(&device->lock);
+
+    res = SendMessageW(g_devices_hwnd, WODM_CLOSE, (WPARAM)hWaveOut, 0);
+
+    if(res == MMSYSERR_NOERROR)
+        WINMM_NotifyClient(&cb_info, WOM_CLOSE, 0, 0);
+
+    return res;
 }
 
 /**************************************************************************
@@ -2978,6 +2996,7 @@ MMRESULT WINAPI waveInOpen(HWAVEIN* lphWaveIn, UINT uDeviceID,
     LRESULT res;
     HRESULT hr;
     WINMM_OpenInfo info;
+    WINMM_CBInfo cb_info;
 
     TRACE("(%p, %x, %p, %lx, %lx, %08x)\n", lphWaveIn, uDeviceID, lpFormat,
             dwCallback, dwInstance, dwFlags);
@@ -3007,6 +3026,13 @@ MMRESULT WINAPI waveInOpen(HWAVEIN* lphWaveIn, UINT uDeviceID,
     if(lphWaveIn)
         *lphWaveIn = (HWAVEIN)info.handle;
 
+    cb_info.flags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
+    cb_info.callback = dwCallback;
+    cb_info.user = dwInstance;
+    cb_info.hwave = info.handle;
+
+    WINMM_NotifyClient(&cb_info, WIM_OPEN, 0, 0);
+
     return res;
 }
 
@@ -3015,12 +3041,30 @@ MMRESULT WINAPI waveInOpen(HWAVEIN* lphWaveIn, UINT uDeviceID,
  */
 UINT WINAPI waveInClose(HWAVEIN hWaveIn)
 {
+    WINMM_Device *device;
+    WINMM_CBInfo cb_info;
+    UINT res;
+
     TRACE("(%p)\n", hWaveIn);
 
     if(!WINMM_StartDevicesThread())
         return MMSYSERR_ERROR;
 
-    return SendMessageW(g_devices_hwnd, WIDM_CLOSE, (WPARAM)hWaveIn, 0);
+    device = WINMM_GetDeviceFromHWAVE((HWAVE)hWaveIn);
+
+    if(!WINMM_ValidateAndLock(device))
+        return MMSYSERR_INVALHANDLE;
+
+    memcpy(&cb_info, &device->cb_info, sizeof(cb_info));
+
+    LeaveCriticalSection(&device->lock);
+
+    res = SendMessageW(g_devices_hwnd, WIDM_CLOSE, (WPARAM)hWaveIn, 0);
+
+    if(res == MMSYSERR_NOERROR)
+        WINMM_NotifyClient(&cb_info, WIM_CLOSE, 0, 0);
+
+    return res;
 }
 
 /**************************************************************************




More information about the wine-cvs mailing list