Commit 4b5d06d3 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

quartz: Fix locking in MediaSeeking and forward SetPosition.

Don't hold locks while forwarding messages, instead rely on the reference count. This prevents some really fun deadlocks from occuring.
parent e1812906
...@@ -32,7 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); ...@@ -32,7 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz);
typedef HRESULT (*SeekFunc)( IMediaSeeking *to, LPVOID arg ); typedef HRESULT (*SeekFunc)( IMediaSeeking *to, LPVOID arg );
static HRESULT ForwardCmdSeek( IBaseFilter* from, SeekFunc fnSeek, LPVOID arg ) static HRESULT ForwardCmdSeek( PCRITICAL_SECTION crit_sect, IBaseFilter* from, SeekFunc fnSeek, LPVOID arg )
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
HRESULT hr_return = S_OK; HRESULT hr_return = S_OK;
...@@ -71,7 +71,9 @@ static HRESULT ForwardCmdSeek( IBaseFilter* from, SeekFunc fnSeek, LPVOID arg ) ...@@ -71,7 +71,9 @@ static HRESULT ForwardCmdSeek( IBaseFilter* from, SeekFunc fnSeek, LPVOID arg )
if (!hr_local) if (!hr_local)
{ {
foundend = TRUE; foundend = TRUE;
LeaveCriticalSection( crit_sect );
hr_local = fnSeek( seek , arg ); hr_local = fnSeek( seek , arg );
EnterCriticalSection( crit_sect );
if (hr_local != E_NOTIMPL) if (hr_local != E_NOTIMPL)
allnotimpl = FALSE; allnotimpl = FALSE;
...@@ -90,7 +92,7 @@ static HRESULT ForwardCmdSeek( IBaseFilter* from, SeekFunc fnSeek, LPVOID arg ) ...@@ -90,7 +92,7 @@ static HRESULT ForwardCmdSeek( IBaseFilter* from, SeekFunc fnSeek, LPVOID arg )
hr = hr_return; hr = hr_return;
out: out:
FIXME("Returning: %08x\n", hr); TRACE("Returning: %08x\n", hr);
return hr; return hr;
} }
...@@ -148,7 +150,9 @@ HRESULT WINAPI MediaSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * ...@@ -148,7 +150,9 @@ HRESULT WINAPI MediaSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD *
if (!pCapabilities) if (!pCapabilities)
return E_POINTER; return E_POINTER;
hr = ForwardCmdSeek(This->pUserData, fwd_checkcaps, pCapabilities); EnterCriticalSection(This->crst);
hr = ForwardCmdSeek(This->crst, This->pUserData, fwd_checkcaps, pCapabilities);
LeaveCriticalSection(This->crst);
if (FAILED(hr) && hr != E_NOTIMPL) if (FAILED(hr) && hr != E_NOTIMPL)
return hr; return hr;
...@@ -217,7 +221,9 @@ HRESULT WINAPI MediaSeekingImpl_SetTimeFormat(IMediaSeeking * iface, const GUID ...@@ -217,7 +221,9 @@ HRESULT WINAPI MediaSeekingImpl_SetTimeFormat(IMediaSeeking * iface, const GUID
MediaSeekingImpl *This = (MediaSeekingImpl *)iface; MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
TRACE("(%s)\n", qzdebugstr_guid(pFormat)); TRACE("(%s)\n", qzdebugstr_guid(pFormat));
ForwardCmdSeek(This->pUserData, fwd_settimeformat, (LPVOID)pFormat); EnterCriticalSection(This->crst);
ForwardCmdSeek(This->crst, This->pUserData, fwd_settimeformat, (LPVOID)pFormat);
LeaveCriticalSection(This->crst);
return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE); return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE);
} }
...@@ -246,7 +252,7 @@ HRESULT WINAPI MediaSeekingImpl_GetDuration(IMediaSeeking * iface, LONGLONG * pD ...@@ -246,7 +252,7 @@ HRESULT WINAPI MediaSeekingImpl_GetDuration(IMediaSeeking * iface, LONGLONG * pD
EnterCriticalSection(This->crst); EnterCriticalSection(This->crst);
*pDuration = This->llDuration; *pDuration = This->llDuration;
ForwardCmdSeek(This->pUserData, fwd_getduration, pDuration); ForwardCmdSeek(This->crst, This->pUserData, fwd_getduration, pDuration);
LeaveCriticalSection(This->crst); LeaveCriticalSection(This->crst);
return S_OK; return S_OK;
...@@ -276,7 +282,7 @@ HRESULT WINAPI MediaSeekingImpl_GetStopPosition(IMediaSeeking * iface, LONGLONG ...@@ -276,7 +282,7 @@ HRESULT WINAPI MediaSeekingImpl_GetStopPosition(IMediaSeeking * iface, LONGLONG
EnterCriticalSection(This->crst); EnterCriticalSection(This->crst);
*pStop = This->llStop; *pStop = This->llStop;
ForwardCmdSeek(This->pUserData, fwd_getstopposition, pStop); ForwardCmdSeek(This->crst, This->pUserData, fwd_getstopposition, pStop);
LeaveCriticalSection(This->crst); LeaveCriticalSection(This->crst);
return S_OK; return S_OK;
...@@ -307,7 +313,7 @@ HRESULT WINAPI MediaSeekingImpl_GetCurrentPosition(IMediaSeeking * iface, LONGLO ...@@ -307,7 +313,7 @@ HRESULT WINAPI MediaSeekingImpl_GetCurrentPosition(IMediaSeeking * iface, LONGLO
EnterCriticalSection(This->crst); EnterCriticalSection(This->crst);
*pCurrent = This->llCurrent; *pCurrent = This->llCurrent;
ForwardCmdSeek(This->pUserData, fwd_getcurposition, pCurrent); ForwardCmdSeek(This->crst, This->pUserData, fwd_getcurposition, pCurrent);
LeaveCriticalSection(This->crst); LeaveCriticalSection(This->crst);
return S_OK; return S_OK;
...@@ -341,14 +347,33 @@ static inline LONGLONG Adjust(LONGLONG value, const LONGLONG * pModifier, DWORD ...@@ -341,14 +347,33 @@ static inline LONGLONG Adjust(LONGLONG value, const LONGLONG * pModifier, DWORD
} }
} }
struct pos_args {
LONGLONG* current, *stop;
DWORD curflags, stopflags;
};
static HRESULT fwd_setposition(IMediaSeeking *seek, LPVOID pargs)
{
struct pos_args *args = (void*)pargs;
return IMediaSeeking_SetPositions(seek, args->current, args->curflags, args->stop, args->stopflags);
}
HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags) HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags)
{ {
MediaSeekingImpl *This = (MediaSeekingImpl *)iface; MediaSeekingImpl *This = (MediaSeekingImpl *)iface;
BOOL bChangeCurrent = FALSE, bChangeStop = FALSE; BOOL bChangeCurrent = FALSE, bChangeStop = FALSE;
LONGLONG llNewCurrent, llNewStop; LONGLONG llNewCurrent, llNewStop;
struct pos_args args;
TRACE("(%p, %x, %p, %x)\n", pCurrent, dwCurrentFlags, pStop, dwStopFlags); TRACE("(%p, %x, %p, %x)\n", pCurrent, dwCurrentFlags, pStop, dwStopFlags);
args.current = pCurrent;
args.stop = pStop;
args.curflags = dwCurrentFlags;
args.stopflags = dwStopFlags;
EnterCriticalSection(This->crst); EnterCriticalSection(This->crst);
llNewCurrent = Adjust(This->llCurrent, pCurrent, dwCurrentFlags); llNewCurrent = Adjust(This->llCurrent, pCurrent, dwCurrentFlags);
...@@ -359,6 +384,8 @@ HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * p ...@@ -359,6 +384,8 @@ HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * p
if (llNewStop != This->llStop) if (llNewStop != This->llStop)
bChangeStop = TRUE; bChangeStop = TRUE;
TRACE("Old: %u, New: %u\n", (DWORD)(This->llCurrent/10000000), (DWORD)(llNewCurrent/10000000));
This->llCurrent = llNewCurrent; This->llCurrent = llNewCurrent;
This->llStop = llNewStop; This->llStop = llNewStop;
...@@ -367,13 +394,14 @@ HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * p ...@@ -367,13 +394,14 @@ HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * p
if (dwStopFlags & AM_SEEKING_ReturnTime) if (dwStopFlags & AM_SEEKING_ReturnTime)
*pStop = llNewStop; *pStop = llNewStop;
ForwardCmdSeek(This->crst, This->pUserData, fwd_setposition, &args);
LeaveCriticalSection(This->crst);
if (bChangeCurrent) if (bChangeCurrent)
This->fnChangeCurrent(This->pUserData); This->fnChangeCurrent(This->pUserData);
if (bChangeStop) if (bChangeStop)
This->fnChangeStop(This->pUserData); This->fnChangeStop(This->pUserData);
LeaveCriticalSection(This->crst);
return S_OK; return S_OK;
} }
...@@ -436,7 +464,7 @@ HRESULT WINAPI MediaSeekingImpl_SetRate(IMediaSeeking * iface, double dRate) ...@@ -436,7 +464,7 @@ HRESULT WINAPI MediaSeekingImpl_SetRate(IMediaSeeking * iface, double dRate)
This->dRate = dRate; This->dRate = dRate;
if (bChangeRate) if (bChangeRate)
hr = This->fnChangeRate(This->pUserData); hr = This->fnChangeRate(This->pUserData);
ForwardCmdSeek(This->pUserData, fwd_setrate, &dRate); ForwardCmdSeek(This->crst, This->pUserData, fwd_setrate, &dRate);
LeaveCriticalSection(This->crst); LeaveCriticalSection(This->crst);
return hr; return hr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment