DirectShow base classes and the possible deadlocks



Hi,

I've analysed the current implementation of the DirectShow interfaces.
I've checked them twice, and I now think that there is still a lot of
"potential" deadlocks.
Let me explain (before flaming):
When using CSource and CSourceStream base classes, whenever you start the
graph, you call <filter>::Run (not directly, but it is called).
1) CBaseFilter::Run locks the filter lock (FilterLock)
2) CBaseFilter::Run then can call CBaseFilter::Pause
3) CBaseFilter::Pause locks the filter lock (okay, it's recursive locking,
but this is a bad design)
4) CBaseFilter::Pause will lock the filter's State lock (FilterStateLock)
twice (by calling GetPin and GetPinCount) and release them
5) CBaseFilter::Pause calls Pin::Active method
6) CSourceStream::Active locks (in that order) :
1) FilterStateLock
2) FilterLock (already locked, but because it's done by the same thread
it's OK)
3) AMThread::AccessLock
4) Wait infinite for AMThread::EventComplete

Okay, now let's see when stopping the graph:
1) CBaseFilter::Stop locks the filter lock (FilterLock)
2) CBaseFilter::Stop will lock the filter's State lock (FilterStateLock)
twice (by calling GetPin and GetPinCount) and release them
3) CBaseFilter::Stop call Pin::Inactive method
4) CSourceStream::Inactive locks (in that order) :
1) FilterStateLock
3) AMThread::AccessLock
4) Wait infinite for AMThread::EventComplete
etc...

So if you look closely to the sequence above, in one case the locking order
is:
FilterLock->FilterStateLock (Inactive)
And in the other case it is:
FilterStateLock->FilterLock (Active)

So if I'm trying to stop the filter in a thread B, and start it back in
thread A, it might deadlock (thread B holding FilterLock and waiting for
FilterStateLock, and thread A holding FilterStateLock and waiting for
FilterLock).

In usual (most) software, it is the same application thread that start and
stop the filter, so the lock is recursively acquired, and the deadlock never
occurs.
The filter state doesn't prevent the lock (just write it down for each step
you'll see)

Of course, this only happen when you call Active directly (step 6 above).
A simple solution to this would be to move the 6-2) step above before the
6-1).
This is done by moving the
296: if(m_pFilter->IsActive()) {
return S_FALSE; // succeeded, but did not allocate resources (they
already exist...)
}
in BaseClasses\Source.cpp up to the line 291

Sincerly,
Cyril




.



Relevant Pages

  • Re: [2.6.16 PATCH] Filesystem Events Connector v4
    ... * The user can set event filter in order to just get those events who concerns, filter may be based on event mask, pid, uid and gid. ... I'll convert to RCU lock. ... but no global lock at least. ...
    (Linux-Kernel)
  • Re: Digital PLL acquisition problem
    ... I want to lock on a 22170 Hz sine signal in 10 ms lock time ... So I put a window at the ouput of my filter to only sweep in a 2600 Hz ...
    (comp.dsp)
  • Re: Digital PLL acquisition problem
    ... I want to lock on a 22170 Hz sine signal in 10 ms lock time ... So I put a window at the ouput of my filter to only sweep in a 2600 Hz ... If you sample the data first, then implement your PLL, a pure-logic state machine frequency/phase detector will have an uncertainty around the edges of +/- 1/2 sample, which quite broad for many purposes. ... Assuming that the tone is strong enough you can get the same effect by estimating the incoming signal's phase and counting rotations -- this works very well in practice, with much noisier signals than you can hope to use a frequency/phase detector on, and doesn't have the edge uncertainty. ...
    (comp.dsp)
  • Re: DirectShow base classes and the possible deadlocks
    ... >> start the filter, and another thread tries to stop the filter, is: ... the CBaseFilter no longer need to lock the FilterLock before ... >thread is blocked because it is waiting for an event in FillBuffer to be set. ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: Digital PLL acquisition problem
    ... I want to lock on a 22170 Hz sine signal in 10 ms lock time ... So I put a window at the ouput of my filter to only sweep in a 2600 Hz ...
    (comp.dsp)