Fix for the i810+Alsa+DSound combination

Francois Gouget fgouget at codeweavers.com
Thu Jan 9 18:43:43 CST 2003


As explained on wine-devel by Ove, the problem with this combination is 
that Alsa claims to support a lot of sound formats and does the format 
conversion to the one format supported by i810 in software. However in 
that case Alsa does not allow mmaping the sound device for obvious 
reasons. This caused DirectSound's mmap to fail and DirectSound just 
deadlocked.

Instead of deadlocking DirectSound should have just used its HEL 
compatibility mode. But that mode did not work because:
  1. the wineoss driver would only create the wineoss thread in the 
non-direct sound case. However when in HEL mode DSound needs a fully 
functional wineoss, and thus that thread.
  2. DSound would only initialize the pwave array if the sound driver 
(here wineoss) did not support DirectSound. However it would then try to 
use it whenever it was unable to obtain a hardware buffer (i.e. whenever 
the mmap failed in wineoss's case).

I fixed 1 by always starting the wineoss thread. If the mmap succeeds 
then we will not use that thread but that should not be a big issue. In 
any case it's not wodOpen's place to decide whether that thread will be 
needed or not (this may mean the thread should be created elsewhere e.g. 
only when a wineoss call requires this thread to exist).
To fix 2 I moved the pwave initialization around so that we allocate the 
pwaves whenever we don't have a hardware buffer and are thus going to be 
using them.


Changelog:

  * dlls/dsound/dsound_main.c,
    dlls/dsound/primary.c,
    dlls/winmm/wineoss/audio.c

    Initialize the pwave array whenever we don't have a hardware buffer.
    Always create the wineoss thread.
    Change the mmap ERR into a TRACE: there are normal circumstances 
where mmap will fail and we can deal with them.


-- 
Francois Gouget
fgouget at codeweavers.com

-------------- next part --------------
Index: dlls/dsound/dsound_main.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound_main.c,v
retrieving revision 1.69
diff -u -r1.69 dsound_main.c
--- dlls/dsound/dsound_main.c	7 Jan 2003 19:43:18 -0000	1.69
+++ dlls/dsound/dsound_main.c	9 Jan 2003 08:18:26 -0000
@@ -468,10 +469,6 @@
 		DeleteCriticalSection(&This->mixlock);
 		if (This->driver) {
 			IDsDriver_Close(This->driver);
-		} else {
-			unsigned c;
-			for (c=0; c<DS_HEL_FRAGS; c++)
-				HeapFree(GetProcessHeap(),0,This->pwave[c]);
 		}
 		if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) {
 			waveOutClose(This->hwo);
@@ -682,28 +683,11 @@
 	if (drv) {
 		IDsDriver_GetCaps(drv,&((*ippDS)->drvcaps));
 	} else {
-		unsigned c;
-
 		/* FIXME: We should check the device capabilities */
 		(*ippDS)->drvcaps.dwFlags =
 			DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYSTEREO;
 		if (ds_emuldriver)
 		    (*ippDS)->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
-
-		/* Allocate memory for HEL buffer headers */
-		for (c=0; c<DS_HEL_FRAGS; c++) {
-			(*ippDS)->pwave[c] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
-			if (!(*ippDS)->pwave[c]) {
-				/* Argh, out of memory */
-				while (c--) {
-					HeapFree(GetProcessHeap(),0,(*ippDS)->pwave[c]);
-					waveOutClose((*ippDS)->hwo);
-					HeapFree(GetProcessHeap(),0,*ippDS);
-					*ippDS = NULL;
-					return DSERR_OUTOFMEMORY;
-				}
-			}
-		}
 	}
 
 	DSOUND_RecalcVolPan(&((*ippDS)->volpan));
Index: dlls/dsound/primary.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/primary.c,v
retrieving revision 1.4
diff -u -r1.4 primary.c
--- dlls/dsound/primary.c	13 Dec 2002 20:26:23 -0000	1.4
+++ dlls/dsound/primary.c	9 Jan 2003 08:18:27 -0000
@@ -176,6 +180,21 @@
 						  &(This->buflen),&(This->buffer),
 						  (LPVOID*)&(This->hwbuf));
 	}
+	if (!This->hwbuf) {
+		/* Allocate memory for HEL buffer headers */
+		unsigned c;
+		for (c=0; c<DS_HEL_FRAGS; c++) {
+			This->pwave[c] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
+			if (!This->pwave[c]) {
+				/* Argh, out of memory */
+				while (c--) {
+					HeapFree(GetProcessHeap(),0,This->pwave[c]);
+				}
+				err=DSERR_OUTOFMEMORY;
+				break;
+			}
+		}
+	}
 	if (err == DS_OK)
 		err = DSOUND_PrimaryOpen(This);
 	if (err != DS_OK)
@@ -191,6 +210,11 @@
 	DSOUND_PrimaryClose(This);
 	if (This->hwbuf) {
 		IDsDriverBuffer_Release(This->hwbuf);
+	} else {
+		unsigned c;
+		for (c=0; c<DS_HEL_FRAGS; c++) {
+			HeapFree(GetProcessHeap(),0,This->pwave[c]);
+		}
 	}
 	return DS_OK;
 }
Index: dlls/winmm/wineoss/audio.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/wineoss/audio.c,v
retrieving revision 1.70
diff -u -r1.70 audio.c
--- dlls/winmm/wineoss/audio.c	7 Jan 2003 23:08:05 -0000	1.70
+++ dlls/winmm/wineoss/audio.c	9 Jan 2003 20:25:47 -0000
@@ -1383,15 +1431,10 @@
 
     OSS_InitRingMessage(&wwo->msgRing);
 
-    if (!(dwFlags & WAVE_DIRECTSOUND)) {
-	wwo->hStartUpEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
-	wwo->hThread = CreateThread(NULL, 0, wodPlayer, (LPVOID)(DWORD)wDevID, 0, &(wwo->dwThreadID));
-	WaitForSingleObject(wwo->hStartUpEvent, INFINITE);
-	CloseHandle(wwo->hStartUpEvent);
-    } else {
-	wwo->hThread = INVALID_HANDLE_VALUE;
-	wwo->dwThreadID = 0;
-    }
+    wwo->hStartUpEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
+    wwo->hThread = CreateThread(NULL, 0, wodPlayer, (LPVOID)(DWORD)wDevID, 0, &(wwo->dwThreadID));
+    WaitForSingleObject(wwo->hStartUpEvent, INFINITE);
+    CloseHandle(wwo->hStartUpEvent);
     wwo->hStartUpEvent = INVALID_HANDLE_VALUE;
 
     TRACE("fd=%d fragmentSize=%ld\n",
@@ -1794,7 +1837,7 @@
 	wwo->mapping = mmap(NULL, wwo->maplen, PROT_WRITE, MAP_SHARED,
 			    wwo->ossdev->fd, 0);
 	if (wwo->mapping == (LPBYTE)-1) {
-	    ERR("(%p): Could not map sound device for direct access (%s)\n", dsdb, strerror(errno));
+	    TRACE("(%p): Could not map sound device for direct access (%s)\n", dsdb, strerror(errno));
 	    return DSERR_GENERIC;
 	}
 	TRACE("(%p): sound device has been mapped for direct access at %p, size=%ld\n", dsdb, wwo->mapping, wwo->maplen);


More information about the wine-patches mailing list