зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1401461. P1 - protect access to ChannelMediaResource::Listener::mResource. r=gerald
MozReview-Commit-ID: 6G1x7cXNvAq --HG-- extra : rebase_source : 2f6a8642930ec314621aab2ce6424e4f9f95e0c2 extra : source : eeb067bc2905dfa6fb5764fd42ebb78e1b71a61d
This commit is contained in:
Родитель
e0f16de8d6
Коммит
f69d8e8e34
|
@ -68,6 +68,7 @@ nsresult
|
||||||
ChannelMediaResource::Listener::OnStartRequest(nsIRequest* aRequest,
|
ChannelMediaResource::Listener::OnStartRequest(nsIRequest* aRequest,
|
||||||
nsISupports* aContext)
|
nsISupports* aContext)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
if (!mResource)
|
if (!mResource)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
return mResource->OnStartRequest(aRequest, mOffset);
|
return mResource->OnStartRequest(aRequest, mOffset);
|
||||||
|
@ -78,6 +79,7 @@ ChannelMediaResource::Listener::OnStopRequest(nsIRequest* aRequest,
|
||||||
nsISupports* aContext,
|
nsISupports* aContext,
|
||||||
nsresult aStatus)
|
nsresult aStatus)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
if (!mResource)
|
if (!mResource)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
return mResource->OnStopRequest(aRequest, aStatus);
|
return mResource->OnStopRequest(aRequest, aStatus);
|
||||||
|
@ -91,8 +93,14 @@ ChannelMediaResource::Listener::OnDataAvailable(nsIRequest* aRequest,
|
||||||
uint32_t aCount)
|
uint32_t aCount)
|
||||||
{
|
{
|
||||||
// This might happen off the main thread.
|
// This might happen off the main thread.
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mResource);
|
RefPtr<ChannelMediaResource> res;
|
||||||
return mResource->OnDataAvailable(mLoadID, aStream, aCount);
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
res = mResource;
|
||||||
|
}
|
||||||
|
// Note Rekove() might happen at the same time to reset mResource. We check
|
||||||
|
// the load ID to determine if the data is from an old channel.
|
||||||
|
return res ? res->OnDataAvailable(mLoadID, aStream, aCount) : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -102,6 +110,8 @@ ChannelMediaResource::Listener::AsyncOnChannelRedirect(
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
nsIAsyncVerifyRedirectCallback* cb)
|
nsIAsyncVerifyRedirectCallback* cb)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (mResource) {
|
if (mResource) {
|
||||||
rv = mResource->OnChannelRedirect(aOld, aNew, aFlags, mOffset);
|
rv = mResource->OnChannelRedirect(aOld, aNew, aFlags, mOffset);
|
||||||
|
@ -127,6 +137,14 @@ ChannelMediaResource::Listener::GetInterface(const nsIID& aIID, void** aResult)
|
||||||
return QueryInterface(aIID, aResult);
|
return QueryInterface(aIID, aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ChannelMediaResource::Listener::Revoke()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
mResource = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsPayloadCompressed(nsIHttpChannel* aChannel)
|
IsPayloadCompressed(nsIHttpChannel* aChannel)
|
||||||
{
|
{
|
||||||
|
@ -415,8 +433,6 @@ ChannelMediaResource::OnDataAvailable(uint32_t aLoadID,
|
||||||
uint32_t aCount)
|
uint32_t aCount)
|
||||||
{
|
{
|
||||||
// This might happen off the main thread.
|
// This might happen off the main thread.
|
||||||
// Don't assert |mChannel.get() == aRequest| since reading mChannel here off
|
|
||||||
// the main thread is a data race.
|
|
||||||
|
|
||||||
RefPtr<ChannelMediaResource> self = this;
|
RefPtr<ChannelMediaResource> self = this;
|
||||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||||
|
|
|
@ -116,7 +116,8 @@ public:
|
||||||
~Listener() {}
|
~Listener() {}
|
||||||
public:
|
public:
|
||||||
Listener(ChannelMediaResource* aResource, int64_t aOffset, uint32_t aLoadID)
|
Listener(ChannelMediaResource* aResource, int64_t aOffset, uint32_t aLoadID)
|
||||||
: mResource(aResource)
|
: mMutex("Listener.mMutex")
|
||||||
|
, mResource(aResource)
|
||||||
, mOffset(aOffset)
|
, mOffset(aOffset)
|
||||||
, mLoadID(aLoadID)
|
, mLoadID(aLoadID)
|
||||||
{}
|
{}
|
||||||
|
@ -128,9 +129,13 @@ public:
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
|
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
|
||||||
|
|
||||||
void Revoke() { mResource = nullptr; }
|
void Revoke();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Mutex mMutex;
|
||||||
|
// mResource should only be modified on the main thread with the lock.
|
||||||
|
// So it can be read without lock on the main thread or on other threads
|
||||||
|
// with the lock.
|
||||||
RefPtr<ChannelMediaResource> mResource;
|
RefPtr<ChannelMediaResource> mResource;
|
||||||
const int64_t mOffset;
|
const int64_t mOffset;
|
||||||
const uint32_t mLoadID;
|
const uint32_t mLoadID;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче