home
products
contribute
download
documentation
forum
Home
Forums
New posts
Search forums
What's new
New posts
All posts
Latest activity
Members
Registered members
Current visitors
Donate
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Search forums
Search titles only
By:
Menu
Log in
Register
Navigation
Install the app
Install
More options
Contact us
Close Menu
Forums
MediaPortal 1
Area 51 - Testing Area
TSWriter deadlock potential fix.
Contact us
RSS
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="mm1352000" data-source="post: 1002469" data-attributes="member: 82144"><p>I'm not sure, but I think our code here is pretty standard.</p><p>I've been reading material like <a href="http://mathinfo.univ-reims.fr/image/mmVideo/cours/DirectShow3Annexe.pdf" target="_blank">this</a> trying to gain some knowledge and context on standard filter locking implementations.</p><p>One thing which I think is a bit unusual in TsWriter is our locking with respect to Receive(). Stick with me here as this gets a bit curly... <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile :)" loading="lazy" data-shortname=":)" /></p><p> </p><p>If you check CMpTsFilterPin::Receive() you'll see we don't lock directly within that function. Use of the receive lock is commented out... which is interesting in itself.</p><p>Having said that, CMpTsFilterPin implements CPacketSync.</p><p>Samples Receive()'d are passed to CPacketSync::OnRawData(). If a complete TS packet is available in the buffer, that function invokes the virtual OnTsPacket() function which is overriden by CMpTsFilterPin. That OnTsPacket() override in turn calls AnalyzeTsPacket() on the main filter object.</p><p>Now here's something that I think could be key: <strong>AnalyzeTsPacket() attempts to acquire the filter lock.</strong></p><p> </p><p>Consider the scenario.</p><p>Filter graph is running. Upstream filter is delivering samples. Everything honky dory.</p><p>TV service decides its time to stop the graph for whatever reason.</p><p>CMpTsFilter:<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite5" alt=":confused:" title="Confused :confused:" loading="lazy" data-shortname=":confused:" />top() is invoked. While the lock is not yet acquired, samples continue to be delivered and nothing changes.</p><p>When the lock is acquired, any sample that completes a TS packet in the CPacketSync buffer will block the streaming thread (because AnalyzeTsPacket() attempts to acquire the same lock held by Stop()).</p><p>Having the streaming thread blocked could be very problematic depending on what CBaseFilter:<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite5" alt=":confused:" title="Confused :confused:" loading="lazy" data-shortname=":confused:" />top() does.</p><p>I would presume that it in some way triggers the upstream filters to be stopped, and if any one of those filters tries to acquire an internal lock on its streaming thread (if it has one) the graph would immediately be in deadlock.</p><p> </p><p>Does that make any sense at all, or is it just nonsense?</p><p>The other thing that is interesting to me is that we return S_FALSE for CMpTsFilterPin::ReceiveCanBlock(). I don't understand that considering the context of the above explanation that a lock is indeed acquired indirectly by the streaming thread.</p><p> </p><p>@<a href="https://forum.team-mediaportal.com/members/tourettes.10858/" target="_blank">tourettes</a> @<a href="https://forum.team-mediaportal.com/members/davidf.19484/" target="_blank">davidf</a> @<a href="https://forum.team-mediaportal.com/members/offbyone.73415/" target="_blank">offbyone</a> @<a href="https://forum.team-mediaportal.com/members/georgius.107951/" target="_blank">georgius</a> @<a href="https://forum.team-mediaportal.com/members/morpheus_xx.48495/" target="_blank">morpheus_xx</a> your thoughts would be most welcome! <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile :)" loading="lazy" data-shortname=":)" /></p><p>Also ping to @[USERGROUP=39]Developers[/USERGROUP] in general. It is high time we figured this out!</p></blockquote><p></p>
[QUOTE="mm1352000, post: 1002469, member: 82144"] I'm not sure, but I think our code here is pretty standard. I've been reading material like [URL='http://mathinfo.univ-reims.fr/image/mmVideo/cours/DirectShow3Annexe.pdf']this[/URL] trying to gain some knowledge and context on standard filter locking implementations. One thing which I think is a bit unusual in TsWriter is our locking with respect to Receive(). Stick with me here as this gets a bit curly... :) If you check CMpTsFilterPin::Receive() you'll see we don't lock directly within that function. Use of the receive lock is commented out... which is interesting in itself. Having said that, CMpTsFilterPin implements CPacketSync. Samples Receive()'d are passed to CPacketSync::OnRawData(). If a complete TS packet is available in the buffer, that function invokes the virtual OnTsPacket() function which is overriden by CMpTsFilterPin. That OnTsPacket() override in turn calls AnalyzeTsPacket() on the main filter object. Now here's something that I think could be key: [B]AnalyzeTsPacket() attempts to acquire the filter lock.[/B] Consider the scenario. Filter graph is running. Upstream filter is delivering samples. Everything honky dory. TV service decides its time to stop the graph for whatever reason. CMpTsFilter::confused:top() is invoked. While the lock is not yet acquired, samples continue to be delivered and nothing changes. When the lock is acquired, any sample that completes a TS packet in the CPacketSync buffer will block the streaming thread (because AnalyzeTsPacket() attempts to acquire the same lock held by Stop()). Having the streaming thread blocked could be very problematic depending on what CBaseFilter::confused:top() does. I would presume that it in some way triggers the upstream filters to be stopped, and if any one of those filters tries to acquire an internal lock on its streaming thread (if it has one) the graph would immediately be in deadlock. Does that make any sense at all, or is it just nonsense? The other thing that is interesting to me is that we return S_FALSE for CMpTsFilterPin::ReceiveCanBlock(). I don't understand that considering the context of the above explanation that a lock is indeed acquired indirectly by the streaming thread. @[URL='https://forum.team-mediaportal.com/members/tourettes.10858/']tourettes[/URL] @[URL='https://forum.team-mediaportal.com/members/davidf.19484/']davidf[/URL] @[URL='https://forum.team-mediaportal.com/members/offbyone.73415/']offbyone[/URL] @[URL='https://forum.team-mediaportal.com/members/georgius.107951/']georgius[/URL] @[URL='https://forum.team-mediaportal.com/members/morpheus_xx.48495/']morpheus_xx[/URL] your thoughts would be most welcome! :) Also ping to @[USERGROUP=39]Developers[/USERGROUP] in general. It is high time we figured this out! [/QUOTE]
Insert quotes…
Verification
Post reply
Forums
MediaPortal 1
Area 51 - Testing Area
TSWriter deadlock potential fix.
Contact us
RSS
Top
Bottom