Made the buffer list in the directsound object thread-safe.
diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c
index 81b0b5d..cc88e7b 100644
--- a/dlls/dsound/dsound_main.c
+++ b/dlls/dsound/dsound_main.c
@@ -98,6 +98,7 @@
IDirectSoundBufferImpl* primary;
IDirectSound3DListenerImpl* listener;
WAVEFORMATEX wfx; /* current main waveformat */
+ CRITICAL_SECTION lock;
};
/*****************************************************************************
@@ -803,7 +804,7 @@
}
/* **** */
- EnterCriticalSection(&(primarybuf->lock));
+ EnterCriticalSection(&(This->dsound->lock));
if (primarybuf->wfx.nSamplesPerSec != wfex->nSamplesPerSec) {
dsb = dsound->buffers;
@@ -829,10 +830,9 @@
primarybuf->wfx.nAvgBytesPerSec =
This->wfx.nSamplesPerSec * This->wfx.nBlockAlign;
-
DSOUND_CloseAudio();
- LeaveCriticalSection(&(primarybuf->lock));
+ LeaveCriticalSection(&(This->dsound->lock));
/* **** */
return DS_OK;
@@ -963,6 +963,7 @@
if (--This->ref)
return This->ref;
+ EnterCriticalSection(&(This->dsound->lock));
for (i=0;i<This->dsound->nrofbuffers;i++)
if (This->dsound->buffers[i] == This)
break;
@@ -973,12 +974,11 @@
This->dsound->nrofbuffers--;
IDirectSound_Release((LPDIRECTSOUND)This->dsound);
}
+ LeaveCriticalSection(&(This->dsound->lock));
DeleteCriticalSection(&(This->lock));
-
if (This->ds3db && ICOM_VTBL(This->ds3db))
IDirectSound3DBuffer_Release((LPDIRECTSOUND3DBUFFER)This->ds3db);
-
if (This->parent)
/* this is a duplicate buffer */
IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER)This->parent);
@@ -1369,12 +1369,15 @@
memcpy(&((*ippdsb)->dsbd),dsbd,sizeof(*dsbd));
+ EnterCriticalSection(&(This->lock));
/* register buffer */
if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
This->buffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl*)*(This->nrofbuffers+1));
This->buffers[This->nrofbuffers] = *ippdsb;
This->nrofbuffers++;
}
+ LeaveCriticalSection(&(This->lock));
+
IDirectSound_AddRef(iface);
if (dsbd->lpwfxFormat)
@@ -1439,10 +1442,12 @@
(*ippdsb)->parent = ipdsb;
memcpy(&((*ippdsb)->wfx), &(ipdsb->wfx), sizeof((*ippdsb)->wfx));
/* register buffer */
+ EnterCriticalSection(&(This->lock));
This->buffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
This->buffers[This->nrofbuffers] = *ippdsb;
This->nrofbuffers++;
IDirectSound_AddRef(iface);
+ LeaveCriticalSection(&(This->lock));
return DS_OK;
}
@@ -2222,7 +2227,7 @@
}
#endif
/* RACE: dsound could be deleted */
- IDirectSound_AddRef((LPDIRECTSOUND)dsound);
+ EnterCriticalSection(&(dsound->lock));
if (primarybuf == NULL) {
/* Should never happen */
WARN("Lost the primary buffer!\n");
@@ -2230,11 +2235,12 @@
ExitThread(0);
}
- /* **** */
EnterCriticalSection(&(primarybuf->lock));
+
len = DSOUND_MixPrimary();
+
LeaveCriticalSection(&(primarybuf->lock));
- /* **** */
+ LeaveCriticalSection(&(dsound->lock));
if (primarybuf->playing)
len = DSOUND_FRAGLEN > len ? DSOUND_FRAGLEN : len;
@@ -2247,7 +2253,6 @@
DSOUND_CloseAudio();
Sleep(100);
}
- IDirectSound_Release((LPDIRECTSOUND)dsound);
}
ExitThread(0);
}
@@ -2309,6 +2314,8 @@
(*ippDS)->wfx.nBlockAlign = 2;
(*ippDS)->wfx.wBitsPerSample = 8;
+ InitializeCriticalSection(&((*ippDS)->lock));
+
if (!dsound) {
HANDLE hnd;
DWORD xid;