Andrew Eikum : winmm: Don't call MMDevAPI during process exit.
Alexandre Julliard
julliard at winehq.org
Fri May 11 11:09:15 CDT 2012
Module: wine
Branch: master
Commit: 47332210dd029379f6fe8a1344225e98e8941257
URL: http://source.winehq.org/git/wine.git/?a=commit;h=47332210dd029379f6fe8a1344225e98e8941257
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Thu May 10 14:17:34 2012 -0500
winmm: Don't call MMDevAPI during process exit.
---
dlls/winmm/waveform.c | 80 ++++++++++++++++++++++++++++++++++++++-----------
dlls/winmm/winmm.c | 33 +++++--------------
2 files changed, 71 insertions(+), 42 deletions(-)
diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c
index a985ee8..602eb06 100644
--- a/dlls/winmm/waveform.c
+++ b/dlls/winmm/waveform.c
@@ -139,6 +139,8 @@ static UINT g_inmmdevices_count;
static IMMDeviceEnumerator *g_devenum;
+#define WINMM_WM_QUIT WM_USER
+
static CRITICAL_SECTION g_devthread_lock;
static CRITICAL_SECTION_DEBUG g_devthread_lock_debug =
{
@@ -185,25 +187,64 @@ void WINMM_DeleteWaveform(void)
{
UINT i, j;
- for(i = 0; i < g_outmmdevices_count; ++i){
- WINMM_MMDevice *mmdevice = &g_out_mmdevices[i];
- for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){
- WINMM_Device *device = mmdevice->devices[j];
- if(device->open)
+ if(g_devices_hwnd){
+ for(i = 0; i < g_outmmdevices_count; ++i){
+ WINMM_MMDevice *mmdevice = &g_out_mmdevices[i];
+ for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){
+ WINMM_Device *device = mmdevice->devices[j];
SendMessageW(g_devices_hwnd, WODM_CLOSE, (WPARAM)device->handle, 0);
+ }
}
- }
- for(i = 0; i < g_inmmdevices_count; ++i){
- WINMM_MMDevice *mmdevice = &g_in_mmdevices[i];
- for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){
- WINMM_Device *device = mmdevice->devices[j];
- if(device->open)
+ for(i = 0; i < g_inmmdevices_count; ++i){
+ WINMM_MMDevice *mmdevice = &g_in_mmdevices[i];
+ for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){
+ WINMM_Device *device = mmdevice->devices[j];
SendMessageW(g_devices_hwnd, WIDM_CLOSE, (WPARAM)device->handle, 0);
+ }
+ }
+
+ SendMessageW(g_devices_hwnd, WINMM_WM_QUIT, 0, 0);
+
+ for(i = 0; i < g_outmmdevices_count; ++i){
+ WINMM_MMDevice *mmdevice = &g_out_mmdevices[i];
+
+ for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){
+ WINMM_Device *device = mmdevice->devices[j];
+ if(device->handle)
+ CloseHandle(device->handle);
+ DeleteCriticalSection(&device->lock);
+ }
+
+ if(mmdevice->volume)
+ ISimpleAudioVolume_Release(mmdevice->volume);
+ CoTaskMemFree(mmdevice->dev_id);
+ DeleteCriticalSection(&mmdevice->lock);
+ }
+
+ for(i = 0; i < g_inmmdevices_count; ++i){
+ WINMM_MMDevice *mmdevice = &g_in_mmdevices[i];
+
+ for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){
+ WINMM_Device *device = mmdevice->devices[j];
+ if(device->handle)
+ CloseHandle(device->handle);
+ DeleteCriticalSection(&device->lock);
+ }
+
+ if(mmdevice->volume)
+ ISimpleAudioVolume_Release(mmdevice->volume);
+ CoTaskMemFree(mmdevice->dev_id);
+ DeleteCriticalSection(&mmdevice->lock);
}
+
+ HeapFree(GetProcessHeap(), 0, g_out_mmdevices);
+ HeapFree(GetProcessHeap(), 0, g_in_mmdevices);
+
+ HeapFree(GetProcessHeap(), 0, g_device_handles);
+ HeapFree(GetProcessHeap(), 0, g_handle_devices);
}
- /* FIXME: Free g_(in,out)_mmdevices? */
DeleteCriticalSection(&g_devthread_lock);
}
@@ -2146,6 +2187,13 @@ static LRESULT CALLBACK WINMM_DevicesMsgProc(HWND hwnd, UINT msg, WPARAM wparam,
case DRV_QUERYDEVICEINTERFACESIZE:
case DRV_QUERYDEVICEINTERFACE:
return DRV_QueryDeviceInterface((WINMM_QueryInterfaceInfo*)wparam);
+ case WINMM_WM_QUIT:
+ TRACE("QUIT message received\n");
+ DestroyWindow(g_devices_hwnd);
+ g_devices_hwnd = NULL;
+ IMMDeviceEnumerator_Release(g_devenum);
+ CoUninitialize();
+ return 0;
}
return DefWindowProcW(hwnd, msg, wparam, lparam);
}
@@ -2200,6 +2248,8 @@ static DWORD WINAPI WINMM_DevicesThreadProc(void *arg)
MSG msg;
if(PeekMessageW(&msg, g_devices_hwnd, 0, 0, PM_REMOVE))
WARN("Unexpected message: 0x%x\n", msg.message);
+ if(!g_devices_hwnd)
+ break;
}else if(wait < g_devhandle_count + WAIT_OBJECT_0){
WINMM_Device *device = g_handle_devices[wait - WAIT_OBJECT_0];
if(device->render)
@@ -2211,12 +2261,6 @@ static DWORD WINAPI WINMM_DevicesThreadProc(void *arg)
GetLastError());
}
- DestroyWindow(g_devices_hwnd);
-
- IMMDeviceEnumerator_Release(g_devenum);
-
- CoUninitialize();
-
return 0;
}
diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c
index 714a84e..26ac410 100644
--- a/dlls/winmm/winmm.c
+++ b/dlls/winmm/winmm.c
@@ -82,18 +82,6 @@ static BOOL WINMM_CreateIData(HINSTANCE hInstDLL)
return TRUE;
}
-/**************************************************************************
- * WINMM_DeleteIData [internal]
- */
-static void WINMM_DeleteIData(void)
-{
- TIME_MMTimeStop();
-
- WINMM_DeleteWaveform();
- CloseHandle(psLastEvent);
- DeleteCriticalSection(&WINMM_cs);
-}
-
/******************************************************************
* WINMM_ErrorToString
*/
@@ -153,20 +141,17 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
return FALSE;
break;
case DLL_PROCESS_DETACH:
- /* close all opened MCI drivers */
+ if(fImpLoad)
+ break;
+
MCI_SendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, 0L);
MMDRV_Exit();
- /* There's no guarantee the drivers haven't already been unloaded on
- * process shutdown.
- */
- if (!fImpLoad)
- {
- /* now unload all remaining drivers... */
- DRIVER_UnloadAll();
- }
-
- WINMM_DeleteIData();
- break;
+ DRIVER_UnloadAll();
+ WINMM_DeleteWaveform();
+ TIME_MMTimeStop();
+ CloseHandle(psLastEvent);
+ DeleteCriticalSection(&WINMM_cs);
+ break;
}
return TRUE;
}
More information about the wine-cvs
mailing list