-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crashes when filters delete unused pins rather than Releasing them #115
Comments
Original comment by |
Original comment by
|
Original comment by |
Original comment by
|
Original comment by
|
Original comment by
|
Original comment by
|
Original comment by
|
This crash can be reproduced by an any filter where pins can be removed during the filter lifetime and those pins inherit from CBasePin without overriding NonDelegatingAddRef and NonDelegatingAddRelease. The default CBasePin implementation uses the filter reference count which implicitly forces the lifetime of the filter and all its pins to be the same. One alternative filter implementation is to AddRef the pin on creation and Release the pin rather than delete when it is removed and override NonDelegatingAddRef and NonDelegatingAddRelease to call the CUnknown implementation. This creates some risk that the pin will reference a deleted filter if the pin lifetime exceeds the filter lifetime but this doesn't happen in practice in Graph Studio Next. This technique is used by the GDCL mp4 mux and demux filters. The inftee sample filter uses a similar but more complex technique. For robustness it would be better if Graph Studio Next did not cache IPin and other interface pointers for pins and retrieved these interface pointers on demand (perhaps by caching the pin ID). However this also requires that all the calling code needs to check for NULL interfaces on every pin access - this change would be hard to test thoroughly. |
The challenge here is that detached pin should start acting as To be able to implement this safely, I suppose at the very least pins On 4/22/2015 7:24 PM, Mike Copperwhite wrote:
|
Modifying the pin to have normal COM reference count and lifetime independent of its parent filter and having the filter Release the pin rather than delete works OK. The pin can't AddRef its parent filter though as this would cause a circular reference count (the filter already has to AddRef the pins it creates) and the filter reference count would never fall to zero. This technique seems robust enough for MSDN sample code and other sample code I've seen. Client code that calls pin interfaces other than AddRef, Release after the filter has been deleted can still cause crashes though (Graph Studio Next doesn't appear to use its cached pin interfaces in dangerous ways like this). In the theory the CBasePin::m_pFilter member could be set to NULL when the pin is no longer needed but this requires extensive checking as the baseclasses do not check for a NULL m_pFilter pointer and generally expect it to be immutable. It would also require locking to make sure it was safe to set/get m_pFilter. |
Pin's AddRef to filter is OK as long as every Release has a check that The question is whether holding only pin reference should keep filter Otherwise with a pin only reference the pin has to detach from filter I suppose both approaches are workable. On 4/23/2015 12:50 PM, Mike Copperwhite wrote:
|
Interesting idea for reference counting, thanks. I suppose the remaining question is whether Graph Studio Next should be made robust against fragile third party filters which delete rather than Release pins before the filter dies (like the OpenCube MXF parser mentioned above). It's quite a big change and not easy to test thoroughly. |
I agree that changing core COM implementation is a kind of a problem and then we're again dealing with issues in external modules and not on our side. It looks like standard implementation of CBasePin::NonDelegatingAddRef/NonDelegatingRelease referencing m_pFilter suggests that all IPin interfaces should be treated as temporary, which is what you started from. I thought that maybe we could keep not just IPin but IPin+IBaseFilter interfaces to extend lifetime of hosting filter, but it won't fix the problem since pin might be deleted by filter and its outstanding interface pointer becomes invalid anyway. |
…ng filter from graph to prevent crashes deleting buggy filters that delete rather than release their output pins when input pins are disconnected
… IPin references of all unaffected pins to prevent buggy filters that delete pins crashing. In RefreshFilters maintain selected filters by matching pin ID rather than IPin interface.
Original issue reported on code.google.com by
[email protected]
on 15 Feb 2013 at 10:53The text was updated successfully, but these errors were encountered: