Bug 1395017. P3 - always dispatch a task to run UpdatePrincipal() even when CacheClientUpdatePrincipal() already runs in the main thread. r=cpearce

When MediaCacheStream::NotifyDataReceived() runs off the main thread,
there is no guarantee that the principal will be updated before the new
data is observable to the consumer because the principal can only be
updated on the main thread while the consumer can access the data off
the main thread.

To make the code simpler, we always dispatch a task to run UpdatePrincipal()
even when CacheClientUpdatePrincipal() already runs in the main thread.

This also avoid the deadlock because ChannelMediaResource::UpdatePrincipal()
will never run with the cache monitor held.

MozReview-Commit-ID: 9CdrJnaV0hl

--HG--
extra : rebase_source : 128d54f4583199e7bfa8c72895583ab7fb668706
extra : intermediate-source : c2310f99bdc7529f1e1c67edbb8274b20b679cb2
extra : source : b6cc234d83e7b18ab69502af78d27ce5eda3b350
This commit is contained in:
JW Wang 2017-08-30 11:42:25 +08:00
parent 3da879e10c
commit 07961dc53c
2 changed files with 3 additions and 12 deletions

View File

@ -1884,19 +1884,16 @@ MediaCacheStream::NotifyDataReceived(int64_t aSize, const char* aData)
// This might happen off the main thread.
MOZ_DIAGNOSTIC_ASSERT(!mClosed);
// Update principals before putting the data in the cache. This is important,
// we want to make sure all principals are updated before any consumer
// can see the new data.
// We do this without holding the cache monitor, in case the client wants
// to do something that takes a lock.
ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
{
// Need to acquire the monitor because this code might run
// off the main thread.
MediaCache::ResourceStreamIterator iter(mMediaCache, mResourceID);
while (MediaCacheStream* stream = iter.Next()) {
stream->mClient->CacheClientUpdatePrincipal();
}
}
ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
int64_t size = aSize;
const char* data = aData;

View File

@ -889,12 +889,6 @@ ChannelMediaResource::UpdatePrincipal()
void
ChannelMediaResource::CacheClientUpdatePrincipal()
{
// This might happen off the main thread.
if (NS_IsMainThread()) {
UpdatePrincipal();
return;
}
SystemGroup::Dispatch(
TaskCategory::Other,
NewRunnableMethod("ChannelMediaResource::UpdatePrincipal",