position-notify array cleanup for IDirectSoundNotify
Jerry Ji
JerryJz at hotmail.com
Sat Mar 22 07:54:04 CST 2003
IDirectSoundNotify8::Release didn't remove notify array from
IDirectSoundBufferImpl. Suppose an application has set notification
positions, and one of the positions is DSBPN_OFFSETSTOP, then it set
some new positions. The new associated events will never be signaled,
even if the application call Release and QueryInterface again before
SetNotificationPositions.
ChangeLog:
- Added position-notify array cleanup for IDirectSoundNotify.
-------------- next part --------------
Index: dlls/dsound/buffer.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/buffer.c,v
retrieving revision 1.7
diff -u -r1.7 buffer.c
--- dlls/dsound/buffer.c 15 Mar 2003 00:54:12 -0000 1.7
+++ dlls/dsound/buffer.c 22 Mar 2003 13:21:07 -0000
@@ -81,12 +81,20 @@
ref = InterlockedDecrement(&(This->ref));
if (!ref) {
- if (This->dsb)
+ if (This->dsb != NULL) {
+ EnterCriticalSection(&This->dsb->lock);
+ if (This->dsb->dsn == This) This->dsb->dsn = NULL;
+ LeaveCriticalSection(&This->dsb->lock);
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
- else if (This->dscb)
+ } else if (This->dscb != NULL) {
+ EnterCriticalSection(&This->dscb->dsound->lock);
+ if (This->dscb->dsn == This) This->dscb->dsn = NULL;
+ LeaveCriticalSection(&This->dscb->dsound->lock);
IDirectSoundCaptureBuffer8_Release((LPDIRECTSOUNDCAPTUREBUFFER8)This->dscb);
+ }
+ if(This->notifies != NULL)
+ HeapFree(GetProcessHeap(), 0, This->notifies);
HeapFree(GetProcessHeap(),0,This);
- return 0;
}
return ref;
}
@@ -101,24 +109,37 @@
TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify);
for (i=0;i<howmuch;i++)
TRACE("notify at %ld to 0x%08lx\n",
- notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
+ notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
}
- if (This->dsb) {
- This->dsb->notifies = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->dsb->notifies,(This->dsb->nrofnotifies+howmuch)*sizeof(DSBPOSITIONNOTIFY));
- memcpy( This->dsb->notifies+This->dsb->nrofnotifies,
- notify,
- howmuch*sizeof(DSBPOSITIONNOTIFY)
- );
- This->dsb->nrofnotifies+=howmuch;
- } else if (This->dscb) {
- TRACE("notifies = %p, nrofnotifies = %d\n", This->dscb->notifies, This->dscb->nrofnotifies);
- This->dscb->notifies = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->dscb->notifies,(This->dscb->nrofnotifies+howmuch)*sizeof(DSBPOSITIONNOTIFY));
- memcpy( This->dscb->notifies+This->dscb->nrofnotifies,
- notify,
- howmuch*sizeof(DSBPOSITIONNOTIFY)
- );
- This->dscb->nrofnotifies+=howmuch;
- TRACE("notifies = %p, nrofnotifies = %d\n", This->dscb->notifies, This->dscb->nrofnotifies);
+
+ LPCRITICAL_SECTION lpcs = NULL;
+ if (This->dsb != NULL && This->dsb->dsn == This)
+ lpcs = &This->dsb->lock;
+ else if (This->dscb != NULL && This->dscb->dsn == This)
+ lpcs = &This->dscb->dsound->lock;
+ if (lpcs != NULL) {
+ if (This->dscb != NULL )
+ IDirectSoundCaptureBuffer_Stop((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb);
+
+ EnterCriticalSection(lpcs);
+
+ /* Just keep one array, Please refer to MSDN or PlatSDK document for detail of
+ * IDirectSoundNotify::SetNotificationPositions */
+ if (This->notifies != NULL) {
+ HeapFree(GetProcessHeap(), 0, This->notifies );
+ }
+ This->notifies = HeapAlloc(GetProcessHeap(), 0, howmuch * sizeof(DSBPOSITIONNOTIFY));
+ memcpy(This->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
+ This->nrofnotifies = howmuch;
+
+ LeaveCriticalSection(lpcs);
+
+ if (This->dscb != NULL) {
+ DSCBCAPS caps;
+ LPDIRECTSOUNDCAPTUREBUFFER dscb = (LPDIRECTSOUNDCAPTUREBUFFER)This->dscb;
+ IDirectSoundCaptureBuffer_GetCaps(dscb, &caps);
+ IDirectSoundCaptureBuffer_Start(dscb, caps.dwFlags);
+ }
}
else
return DSERR_INVALIDPARAM;
@@ -819,12 +840,24 @@
if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
IDirectSoundNotifyImpl *dsn;
- dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*dsn));
- dsn->ref = 1;
- dsn->dsb = This;
- dsn->dscb = 0;
+ /* Since we don't call IDirectSoundNotify_AddRef for This->dsn (don't know where
+ * we whould release it), we must Prevent IDirectSoundNotify_Release from changing
+ * This->dsn manually */
+ EnterCriticalSection(&This->lock);
+ if ( This->dsn != NULL && IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->dsn) <= 1 ) {
+ This->dsn = NULL;
+ }
+ LeaveCriticalSection(&This->lock);
+ dsn = This->dsn;
+ if(dsn == NULL) {
+ dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*dsn));
+ dsn->ref = 1;
+ dsn->dsb = This;
+ dsn->dscb = 0;
+ This->dsn = dsn;
+ ICOM_VTBL(dsn) = &dsnvt;
+ }
IDirectSoundBuffer8_AddRef(iface);
- ICOM_VTBL(dsn) = &dsnvt;
*ppobj = (LPVOID)dsn;
return S_OK;
}
Index: dlls/dsound/capture.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/capture.c,v
retrieving revision 1.7
diff -u -r1.7 capture.c
--- dlls/dsound/capture.c 15 Mar 2003 00:54:12 -0000 1.7
+++ dlls/dsound/capture.c 22 Mar 2003 13:21:10 -0000
@@ -300,8 +300,8 @@
}
This->index = (This->index + 1) % This->nrofpwaves;
waveInUnprepareHeader(hwi,&(This->pwave[This->index]),sizeof(WAVEHDR));
- if (This->capture_buffer->nrofnotifies)
- SetEvent(This->capture_buffer->notifies[This->index].hEventNotify);
+ if (This->capture_buffer->dsn != NULL && This->capture_buffer->dsn->nrofnotifies != 0)
+ SetEvent(This->capture_buffer->dsn->notifies[This->index].hEventNotify);
if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) {
TRACE("end of buffer\n");
This->state = STATE_STOPPED;
@@ -696,14 +696,23 @@
if (IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
IDirectSoundNotifyImpl *dsn;
- dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),0,
- sizeof(*dsn));
- dsn->ref = 1;
- dsn->dsb = 0;
- dsn->dscb = This;
- /* FIXME: get this right someday */
- IDirectSoundCaptureBuffer8_AddRef(iface);
- ICOM_VTBL(dsn) = &dsnvt;
+ /* Since we don't call IDirectSoundNotify_AddRef for This->dsn (don't know where
+ * we whould release it), we must Prevent IDirectSoundNotify_Release from changing
+ * This->dsn manually */
+ EnterCriticalSection(&This->dsound->lock);
+ if ( This->dsn != NULL && IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->dsn) <= 1 ) {
+ This->dsn = NULL;
+ }
+ LeaveCriticalSection(&This->dsound->lock);
+ dsn = This->dsn;
+ if(dsn == NULL) {
+ dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*dsn));
+ dsn->ref = 1;
+ dsn->dsb = 0;
+ dsn->dscb = This;
+ ICOM_VTBL(dsn) = &dsnvt;
+ }
+ IDirectSoundCaptureBuffer8_AddRef(iface);
*ppobj = (LPVOID)dsn;
return DS_OK;
}
@@ -778,9 +787,6 @@
else
ERR("does not reference dsound\n");
- if (This->notifies)
- HeapFree(GetProcessHeap(),0, This->notifies);
-
HeapFree( GetProcessHeap(), 0, This );
}
@@ -1037,10 +1043,10 @@
IDirectSoundCaptureImpl* ipDSC = This->dsound;
if (ipDSC->buffer) {
- if (This->nrofnotifies) {
+ if (This->dsn != NULL && This->dsn->nrofnotifies != 0) {
unsigned c;
- ipDSC->nrofpwaves = This->nrofnotifies;
+ ipDSC->nrofpwaves = This->dsn->nrofnotifies;
/* prepare headers */
ipDSC->pwave = HeapReAlloc(GetProcessHeap(),0,ipDSC->pwave,
@@ -1049,14 +1055,14 @@
for (c = 0; c < ipDSC->nrofpwaves; c++) {
if (c == 0) {
ipDSC->pwave[0].lpData = ipDSC->buffer;
- ipDSC->pwave[0].dwBufferLength =
- This->notifies[0].dwOffset + 1;
+ ipDSC->pwave[0].dwBufferLength =
+ This->dsn->notifies[0].dwOffset + 1;
} else {
- ipDSC->pwave[c].lpData = ipDSC->buffer +
- This->notifies[c-1].dwOffset + 1;
- ipDSC->pwave[c].dwBufferLength =
- This->notifies[c].dwOffset -
- This->notifies[c-1].dwOffset;
+ ipDSC->pwave[c].lpData = ipDSC->buffer +
+ This->dsn->notifies[c-1].dwOffset + 1;
+ ipDSC->pwave[c].dwBufferLength =
+ This->dsn->notifies[c].dwOffset -
+ This->dsn->notifies[c-1].dwOffset;
}
ipDSC->pwave[c].dwUser = (DWORD)ipDSC;
ipDSC->pwave[c].dwFlags = 0;
Index: dlls/dsound/dsound_private.h
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound_private.h,v
retrieving revision 1.5
diff -u -r1.5 dsound_private.h
--- dlls/dsound/dsound_private.h 15 Mar 2003 00:54:12 -0000 1.5
+++ dlls/dsound/dsound_private.h 22 Mar 2003 13:21:11 -0000
@@ -117,8 +117,7 @@
DWORD primary_mixpos, buf_mixpos;
BOOL need_remix;
/* IDirectSoundNotifyImpl fields */
- LPDSBPOSITIONNOTIFY notifies;
- int nrofnotifies;
+ IDirectSoundNotifyImpl *dsn;
};
HRESULT WINAPI SecondaryBuffer_Create(
@@ -189,8 +188,7 @@
IDirectSoundCaptureImpl* dsound;
/* FIXME: don't need this */
LPDSCBUFFERDESC pdscbd;
- LPDSBPOSITIONNOTIFY notifies;
- int nrofnotifies;
+ IDirectSoundNotifyImpl *dsn;
DWORD flags;
};
@@ -218,6 +216,9 @@
/* IDirectSoundNotifyImpl fields */
IDirectSoundBufferImpl* dsb;
IDirectSoundCaptureBufferImpl* dscb;
+ /* position-notify array */
+ LPDSBPOSITIONNOTIFY notifies;
+ int nrofnotifies;
};
/*****************************************************************************
Index: dlls/dsound/mixer.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/mixer.c,v
retrieving revision 1.10
diff -u -r1.10 mixer.c
--- dlls/dsound/mixer.c 17 Mar 2003 21:23:12 -0000 1.10
+++ dlls/dsound/mixer.c 22 Mar 2003 13:21:14 -0000
@@ -79,13 +79,13 @@
DWORD offset;
LPDSBPOSITIONNOTIFY event;
- if (dsb->nrofnotifies == 0)
+ if (dsb->dsn == NULL || dsb->dsn->nrofnotifies == 0)
return;
TRACE("(%p) buflen = %ld, playpos = %ld, len = %d\n",
dsb, dsb->buflen, dsb->playpos, len);
- for (i = 0; i < dsb->nrofnotifies ; i++) {
- event = dsb->notifies + i;
+ for (i = 0; i < dsb->dsn->nrofnotifies ; i++) {
+ event = dsb->dsn->notifies + i;
offset = event->dwOffset;
TRACE("checking %d, position %ld, event = %p\n",
i, offset, event->hEventNotify);
More information about the wine-patches
mailing list