зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1338493 - Part 2, move HttpBackgroundChannelChild to socket transport thread. r=mayhemer
Move HttpBackgroundChannelChild from main thread to socket transport thread. Allow HttpChannelChild.mBgChild to be used on both main thread and STS thread under mutex protection. MozReview-Commit-ID: 9WAXmJLr8HT --HG-- extra : rebase_source : 774c71cec9d36412e2101719f5ca930a214f6472
This commit is contained in:
Родитель
69d4008264
Коммит
0f8c26e1d3
|
@ -11,12 +11,12 @@
|
|||
#include "HttpBackgroundChannelChild.h"
|
||||
|
||||
#include "HttpChannelChild.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIIPCBackgroundChildCreateCallback.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
|
||||
using mozilla::ipc::BackgroundChild;
|
||||
using mozilla::ipc::IPCResult;
|
||||
|
@ -35,6 +35,7 @@ public:
|
|||
explicit BackgroundChannelCreateCallback(HttpBackgroundChannelChild* aBgChild)
|
||||
: mBgChild(aBgChild)
|
||||
{
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_ASSERT(aBgChild);
|
||||
}
|
||||
|
||||
|
@ -50,7 +51,7 @@ NS_IMPL_ISUPPORTS(BackgroundChannelCreateCallback,
|
|||
void
|
||||
BackgroundChannelCreateCallback::ActorCreated(PBackgroundChild* aActor)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(mBgChild);
|
||||
|
||||
|
@ -70,12 +71,14 @@ BackgroundChannelCreateCallback::ActorCreated(PBackgroundChild* aActor)
|
|||
// hold extra reference for IPDL
|
||||
RefPtr<HttpBackgroundChannelChild> child = mBgChild;
|
||||
Unused << child.forget().take();
|
||||
|
||||
mBgChild->mChannelChild->OnBackgroundChildReady(mBgChild);
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundChannelCreateCallback::ActorFailed()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_ASSERT(mBgChild);
|
||||
|
||||
mBgChild->OnBackgroundChannelCreationFailed();
|
||||
|
@ -95,7 +98,7 @@ HttpBackgroundChannelChild::Init(HttpChannelChild* aChannelChild)
|
|||
{
|
||||
LOG(("HttpBackgroundChannelChild::Init [this=%p httpChannel=%p channelId=%"
|
||||
PRIu64 "]\n", this, aChannelChild, aChannelChild->ChannelId()));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
NS_ENSURE_ARG(aChannelChild);
|
||||
|
||||
mChannelChild = aChannelChild;
|
||||
|
@ -112,7 +115,7 @@ void
|
|||
HttpBackgroundChannelChild::OnChannelClosed()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::OnChannelClosed [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
// HttpChannelChild is not going to handle any incoming message.
|
||||
mChannelChild = nullptr;
|
||||
|
@ -122,7 +125,7 @@ void
|
|||
HttpBackgroundChannelChild::OnStartRequestReceived()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::OnStartRequestReceived [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_ASSERT(mChannelChild);
|
||||
MOZ_ASSERT(!mStartReceived); // Should only be called once.
|
||||
|
||||
|
@ -146,11 +149,11 @@ HttpBackgroundChannelChild::OnBackgroundChannelCreationFailed()
|
|||
{
|
||||
LOG(("HttpBackgroundChannelChild::OnBackgroundChannelCreationFailed"
|
||||
" [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (mChannelChild) {
|
||||
RefPtr<HttpChannelChild> channelChild = mChannelChild.forget();
|
||||
channelChild->FailedAsyncOpen(NS_ERROR_UNEXPECTED);
|
||||
channelChild->OnBackgroundChildDestroyed(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +161,7 @@ bool
|
|||
HttpBackgroundChannelChild::CreateBackgroundChannel()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::CreateBackgroundChannel [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
RefPtr<BackgroundChannelCreateCallback> callback =
|
||||
new BackgroundChannelCreateCallback(this);
|
||||
|
@ -169,6 +172,7 @@ HttpBackgroundChannelChild::CreateBackgroundChannel()
|
|||
bool
|
||||
HttpBackgroundChannelChild::IsWaitingOnStartRequest()
|
||||
{
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
// Need to wait for OnStartRequest if it is sent by
|
||||
// parent process but not received by content process.
|
||||
return (mStartSent && !mStartReceived);
|
||||
|
@ -179,7 +183,7 @@ IPCResult
|
|||
HttpBackgroundChannelChild::RecvOnStartRequestSent()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvOnStartRequestSent [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_ASSERT(!mStartSent); // Should only receive this message once.
|
||||
|
||||
mStartSent = true;
|
||||
|
@ -195,7 +199,7 @@ HttpBackgroundChannelChild::RecvOnTransportAndData(
|
|||
const nsCString& aData)
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvOnTransportAndData [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -210,7 +214,7 @@ HttpBackgroundChannelChild::RecvOnTransportAndData(
|
|||
const uint64_t,
|
||||
const uint32_t,
|
||||
const nsCString>(
|
||||
"net::HttpBackgroundChannelChild::RecvOnTransportAndData",
|
||||
"HttpBackgroundChannelChild::RecvOnTransportAndData",
|
||||
this,
|
||||
&HttpBackgroundChannelChild::RecvOnTransportAndData,
|
||||
aChannelStatus,
|
||||
|
@ -237,7 +241,7 @@ HttpBackgroundChannelChild::RecvOnStopRequest(
|
|||
const ResourceTimingStruct& aTiming)
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvOnStopRequest [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -249,7 +253,7 @@ HttpBackgroundChannelChild::RecvOnStopRequest(
|
|||
|
||||
mQueuedRunnables.AppendElement(
|
||||
NewRunnableMethod<const nsresult, const ResourceTimingStruct>(
|
||||
"net::HttpBackgroundChannelChild::RecvOnStopRequest",
|
||||
"HttpBackgroundChannelChild::RecvOnStopRequest",
|
||||
this,
|
||||
&HttpBackgroundChannelChild::RecvOnStopRequest,
|
||||
aChannelStatus,
|
||||
|
@ -269,7 +273,7 @@ HttpBackgroundChannelChild::RecvOnProgress(const int64_t& aProgress,
|
|||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvOnProgress [this=%p progress=%"
|
||||
PRId64 " max=%" PRId64 "]\n", this, aProgress, aProgressMax));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -281,7 +285,7 @@ HttpBackgroundChannelChild::RecvOnProgress(const int64_t& aProgress,
|
|||
|
||||
mQueuedRunnables.AppendElement(
|
||||
NewRunnableMethod<const int64_t, const int64_t>(
|
||||
"net::HttpBackgroundChannelChild::RecvOnProgress",
|
||||
"HttpBackgroundChannelChild::RecvOnProgress",
|
||||
this,
|
||||
&HttpBackgroundChannelChild::RecvOnProgress,
|
||||
aProgress,
|
||||
|
@ -300,7 +304,7 @@ HttpBackgroundChannelChild::RecvOnStatus(const nsresult& aStatus)
|
|||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvOnStatus [this=%p status=%"
|
||||
PRIx32 "]\n", this, static_cast<uint32_t>(aStatus)));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -311,7 +315,7 @@ HttpBackgroundChannelChild::RecvOnStatus(const nsresult& aStatus)
|
|||
static_cast<uint32_t>(aStatus)));
|
||||
|
||||
mQueuedRunnables.AppendElement(NewRunnableMethod<const nsresult>(
|
||||
"net::HttpBackgroundChannelChild::RecvOnStatus",
|
||||
"HttpBackgroundChannelChild::RecvOnStatus",
|
||||
this,
|
||||
&HttpBackgroundChannelChild::RecvOnStatus,
|
||||
aStatus));
|
||||
|
@ -328,7 +332,7 @@ IPCResult
|
|||
HttpBackgroundChannelChild::RecvFlushedForDiversion()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -338,7 +342,7 @@ HttpBackgroundChannelChild::RecvFlushedForDiversion()
|
|||
LOG((" > pending until OnStartRequest\n"));
|
||||
|
||||
mQueuedRunnables.AppendElement(NewRunnableMethod(
|
||||
"net::HttpBackgroundChannelChild::RecvFlushedForDiversion",
|
||||
"HttpBackgroundChannelChild::RecvFlushedForDiversion",
|
||||
this,
|
||||
&HttpBackgroundChannelChild::RecvFlushedForDiversion));
|
||||
|
||||
|
@ -354,7 +358,7 @@ IPCResult
|
|||
HttpBackgroundChannelChild::RecvDivertMessages()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvDivertMessages [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -364,7 +368,7 @@ HttpBackgroundChannelChild::RecvDivertMessages()
|
|||
LOG((" > pending until OnStartRequest\n"));
|
||||
|
||||
mQueuedRunnables.AppendElement(
|
||||
NewRunnableMethod("net::HttpBackgroundChannelChild::RecvDivertMessages",
|
||||
NewRunnableMethod("HttpBackgroundChannelChild::RecvDivertMessages",
|
||||
this,
|
||||
&HttpBackgroundChannelChild::RecvDivertMessages));
|
||||
|
||||
|
@ -380,7 +384,7 @@ IPCResult
|
|||
HttpBackgroundChannelChild::RecvNotifyTrackingProtectionDisabled()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvNotifyTrackingProtectionDisabled [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -397,7 +401,7 @@ IPCResult
|
|||
HttpBackgroundChannelChild::RecvNotifyTrackingResource()
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvNotifyTrackingResource [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -414,7 +418,7 @@ IPCResult
|
|||
HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo(const ClassifierInfo& info)
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
if (NS_WARN_IF(!mChannelChild)) {
|
||||
return IPC_OK();
|
||||
|
@ -431,7 +435,22 @@ void
|
|||
HttpBackgroundChannelChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
LOG(("HttpBackgroundChannelChild::ActorDestroy[this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!OnSocketThread()) {
|
||||
// PBackgroundChild might be destroyed during shutdown and
|
||||
// ActorDestroy will be called on main thread directly.
|
||||
// Simply disconnect with HttpChannelChild to release memory.
|
||||
mChannelChild = nullptr;
|
||||
RefPtr<HttpBackgroundChannelChild> self = this;
|
||||
mQueuedRunnables.AppendElement(NS_NewRunnableFunction(
|
||||
"HttpBackgroundChannelChild::ActorDestroyNonSTSThread", [self]() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
self->mChannelChild = nullptr;
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
// Ensure all IPC messages received before ActorDestroy can be
|
||||
// handled correctly. If there is any pending IPC message, destroyed
|
||||
|
@ -440,12 +459,12 @@ HttpBackgroundChannelChild::ActorDestroy(ActorDestroyReason aWhy)
|
|||
LOG((" > pending until queued messages are flushed\n"));
|
||||
RefPtr<HttpBackgroundChannelChild> self = this;
|
||||
mQueuedRunnables.AppendElement(NS_NewRunnableFunction(
|
||||
"net::HttpBackgroundChannelChild::ActorDestroy", [self]() {
|
||||
"HttpBackgroundChannelChild::ActorDestroy", [self]() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<HttpChannelChild> channelChild = self->mChannelChild.forget();
|
||||
|
||||
if (channelChild) {
|
||||
channelChild->OnBackgroundChildDestroyed();
|
||||
channelChild->OnBackgroundChildDestroyed(self);
|
||||
}
|
||||
}));
|
||||
return;
|
||||
|
@ -454,7 +473,7 @@ HttpBackgroundChannelChild::ActorDestroy(ActorDestroyReason aWhy)
|
|||
if (mChannelChild) {
|
||||
RefPtr<HttpChannelChild> channelChild = mChannelChild.forget();
|
||||
|
||||
channelChild->OnBackgroundChildDestroyed();
|
||||
channelChild->OnBackgroundChildDestroyed(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,13 +95,16 @@ private:
|
|||
RefPtr<HttpChannelChild> mChannelChild;
|
||||
|
||||
// True if OnStartRequest is received by HttpChannelChild.
|
||||
// Should only access on STS thread.
|
||||
bool mStartReceived = false;
|
||||
|
||||
// True if OnStartRequest is sent by HttpChannelParent.
|
||||
// Should only access on STS thread.
|
||||
bool mStartSent = false;
|
||||
|
||||
// Store pending messages that require to be handled after OnStartRequest.
|
||||
// Should be flushed after OnStartRequest is received and handled.
|
||||
// Should only access on STS thread.
|
||||
nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
|
||||
};
|
||||
|
||||
|
|
|
@ -499,7 +499,7 @@ protected:
|
|||
nsCString mEntityID;
|
||||
uint64_t mStartPos;
|
||||
|
||||
nsresult mStatus;
|
||||
Atomic<nsresult, ReleaseAcquire> mStatus;
|
||||
uint32_t mLoadFlags;
|
||||
uint32_t mCaps;
|
||||
uint32_t mClassOfService;
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsIDOMWindowUtils.h"
|
||||
#include "nsIEventTarget.h"
|
||||
#include "nsRedirectHistoryEntry.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
|
@ -177,6 +178,7 @@ HttpChannelChild::HttpChannelChild()
|
|||
, mPostRedirectChannelShouldUpgrade(false)
|
||||
, mShouldParentIntercept(false)
|
||||
, mSuspendParentAfterSynthesizeResponse(false)
|
||||
, mBgChildMutex("HttpChannelChild::BgChildMutex")
|
||||
, mEventTargetMutex("HttpChannelChild::EventTargetMutex")
|
||||
{
|
||||
LOG(("Creating HttpChannelChild @%p\n", this));
|
||||
|
@ -295,19 +297,46 @@ HttpChannelChild::OnBackgroundChildReady(HttpBackgroundChannelChild* aBgChild)
|
|||
{
|
||||
LOG(("HttpChannelChild::OnBackgroundChildReady [this=%p, bgChild=%p]\n",
|
||||
this, aBgChild));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mBgChild);
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
MOZ_ASSERT(mBgChild == aBgChild);
|
||||
{
|
||||
MutexAutoLock lock(mBgChildMutex);
|
||||
|
||||
// mBgChild might be removed or replaced while the original background
|
||||
// channel is inited on STS thread.
|
||||
if (mBgChild != aBgChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mBgInitFailCallback);
|
||||
mBgInitFailCallback = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::OnBackgroundChildDestroyed()
|
||||
HttpChannelChild::OnBackgroundChildDestroyed(HttpBackgroundChannelChild* aBgChild)
|
||||
{
|
||||
LOG(("HttpChannelChild::OnBackgroundChildDestroyed [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
mBgChild = nullptr;
|
||||
nsCOMPtr<nsIRunnable> callback;
|
||||
{
|
||||
MutexAutoLock lock(mBgChildMutex);
|
||||
|
||||
// mBgChild might be removed or replaced while the original background
|
||||
// channel is destroyed on STS thread.
|
||||
if (aBgChild != mBgChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBgChild = nullptr;
|
||||
callback = mBgInitFailCallback.forget();
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
|
||||
neckoTarget->Dispatch(callback, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
class AssociateApplicationCacheEvent : public NeckoTargetChannelEvent<HttpChannelChild>
|
||||
|
@ -459,9 +488,23 @@ HttpChannelChild::RecvOnStartRequest(const nsresult& channelStatus,
|
|||
selfAddr, peerAddr, cacheKey,
|
||||
altDataType, altDataLen));
|
||||
|
||||
MOZ_ASSERT(mBgChild);
|
||||
if (mBgChild) {
|
||||
mBgChild->OnStartRequestReceived();
|
||||
{
|
||||
// Child's mEventQ is to control the execution order of the IPC messages
|
||||
// from both main thread IPDL and PBackground IPDL.
|
||||
// To guarantee the ordering, PBackground IPC messages that are sent after
|
||||
// OnStartRequest will be throttled until OnStartRequest hits the Child's
|
||||
// mEventQ.
|
||||
MutexAutoLock lock(mBgChildMutex);
|
||||
|
||||
if (mBgChild) {
|
||||
MOZ_RELEASE_ASSERT(gSocketTransportService);
|
||||
DebugOnly<nsresult> rv =
|
||||
gSocketTransportService->Dispatch(
|
||||
NewRunnableMethod(
|
||||
"HttpBackgroundChannelChild::OnStartRequestReceived",
|
||||
mBgChild, &HttpBackgroundChannelChild::OnStartRequestReceived),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
|
@ -697,7 +740,7 @@ HttpChannelChild::ProcessOnTransportAndData(const nsresult& aChannelStatus,
|
|||
const nsCString& aData)
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessOnTransportAndData [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
|
||||
"Should not be receiving any more callbacks from parent!");
|
||||
mEventQ->RunOrEnqueue(new TransportAndDataEvent(this, aChannelStatus,
|
||||
|
@ -756,6 +799,7 @@ HttpChannelChild::OnTransportAndData(const nsresult& channelStatus,
|
|||
|
||||
// For diversion to parent, just SendDivertOnDataAvailable.
|
||||
if (mDivertingToParent) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
|
||||
"Should not be processing any more callbacks from parent!");
|
||||
|
||||
|
@ -769,6 +813,7 @@ HttpChannelChild::OnTransportAndData(const nsresult& channelStatus,
|
|||
if (mUnknownDecoderInvolved) {
|
||||
LOG(("UnknownDecoder is involved queue OnDataAvailable call. [this=%p]",
|
||||
this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mUnknownDecoderEventQ.AppendElement(
|
||||
MakeUnique<MaybeDivertOnDataHttpEvent>(this, data, offset, count));
|
||||
}
|
||||
|
@ -923,7 +968,7 @@ HttpChannelChild::ProcessOnStopRequest(const nsresult& aChannelStatus,
|
|||
const ResourceTimingStruct& aTiming)
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessOnStopRequest [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
|
||||
"Should not be receiving any more callbacks from parent!");
|
||||
|
||||
|
@ -953,7 +998,8 @@ void
|
|||
HttpChannelChild::MaybeDivertOnStop(const nsresult& aChannelStatus)
|
||||
{
|
||||
LOG(("HttpChannelChild::MaybeDivertOnStop [this=%p, "
|
||||
"mDivertingToParent=%d status=%" PRIx32 "]", this, mDivertingToParent,
|
||||
"mDivertingToParent=%d status=%" PRIx32 "]", this,
|
||||
static_cast<bool>(mDivertingToParent),
|
||||
static_cast<uint32_t>(aChannelStatus)));
|
||||
if (mDivertingToParent) {
|
||||
SendDivertOnStopRequest(aChannelStatus);
|
||||
|
@ -976,35 +1022,10 @@ HttpChannelChild::OnStopRequest(const nsresult& channelStatus,
|
|||
return;
|
||||
}
|
||||
|
||||
// In thread retargeting is enabled, there might be Runnable for
|
||||
// DoOnStatus/DoOnProgress sit in the main thread event target. We need to
|
||||
// ensure OnStopRequest is fired after that by postponing the
|
||||
// ChannelEventQueue processing to the end of main thread event target.
|
||||
// This workaround can be removed after bug 1338493 is complete.
|
||||
if (mODATarget) {
|
||||
{
|
||||
MutexAutoLock lock(mEventTargetMutex);
|
||||
mODATarget = nullptr;
|
||||
}
|
||||
mEventQ->Suspend();
|
||||
UniquePtr<ChannelEvent> stopEvent =
|
||||
MakeUnique<StopRequestEvent>(this, channelStatus, timing);
|
||||
mEventQ->PrependEvent(stopEvent);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
|
||||
MOZ_ASSERT(neckoTarget);
|
||||
|
||||
DebugOnly<nsresult> rv = neckoTarget->Dispatch(
|
||||
NewRunnableMethod(
|
||||
"net::ChannelEventQueue::Resume", mEventQ, &ChannelEventQueue::Resume),
|
||||
NS_DISPATCH_NORMAL);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mUnknownDecoderInvolved) {
|
||||
LOG(("UnknownDecoder is involved queue OnStopRequest call. [this=%p]",
|
||||
this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mUnknownDecoderEventQ.AppendElement(
|
||||
MakeUnique<MaybeDivertOnStopHttpEvent>(this, channelStatus));
|
||||
}
|
||||
|
@ -1160,7 +1181,7 @@ HttpChannelChild::ProcessOnProgress(const int64_t& aProgress,
|
|||
const int64_t& aProgressMax)
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessOnProgress [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
mEventQ->RunOrEnqueue(new ProgressEvent(this, aProgress, aProgressMax));
|
||||
}
|
||||
|
||||
|
@ -1208,7 +1229,7 @@ void
|
|||
HttpChannelChild::ProcessOnStatus(const nsresult& aStatus)
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessOnStatus [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
mEventQ->RunOrEnqueue(new StatusEvent(this, aStatus));
|
||||
}
|
||||
|
||||
|
@ -1299,21 +1320,26 @@ HttpChannelChild::FailedAsyncOpen(const nsresult& status)
|
|||
void
|
||||
HttpChannelChild::CleanupBackgroundChannel()
|
||||
{
|
||||
MutexAutoLock lock(mBgChildMutex);
|
||||
|
||||
LOG(("HttpChannelChild::CleanupBackgroundChannel [this=%p bgChild=%p]\n",
|
||||
this, mBgChild.get()));
|
||||
|
||||
mBgInitFailCallback = nullptr;
|
||||
|
||||
if (!mBgChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> bgChild = mBgChild.forget();
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
SystemGroup::Dispatch(
|
||||
"HttpChannelChild::CleanupBackgroundChannel",
|
||||
TaskCategory::Other,
|
||||
NewRunnableMethod("net::HttpBackgroundChannelChild::OnChannelClosed",
|
||||
bgChild,
|
||||
&HttpBackgroundChannelChild::OnChannelClosed));
|
||||
MOZ_RELEASE_ASSERT(gSocketTransportService);
|
||||
if (!OnSocketThread()) {
|
||||
gSocketTransportService->Dispatch(
|
||||
NewRunnableMethod(
|
||||
"HttpBackgroundChannelChild::OnChannelClosed",
|
||||
bgChild, &HttpBackgroundChannelChild::OnChannelClosed),
|
||||
NS_DISPATCH_NORMAL);
|
||||
} else {
|
||||
bgChild->OnChannelClosed();
|
||||
}
|
||||
|
@ -1685,7 +1711,7 @@ void
|
|||
HttpChannelChild::ProcessFlushedForDiversion()
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessFlushedForDiversion [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_RELEASE_ASSERT(mDivertingToParent);
|
||||
|
||||
mEventQ->RunOrEnqueue(new HttpFlushedForDiversionEvent(this), true);
|
||||
|
@ -1695,18 +1721,31 @@ void
|
|||
HttpChannelChild::ProcessNotifyTrackingProtectionDisabled()
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessNotifyTrackingProtectionDisabled [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
nsChannelClassifier::NotifyTrackingProtectionDisabled(this);
|
||||
RefPtr<HttpChannelChild> self = this;
|
||||
nsCOMPtr<nsIEventTarget> mainTarget = GetMainThreadEventTarget();
|
||||
mainTarget->Dispatch(
|
||||
NS_NewRunnableFunction(
|
||||
"nsChannelClassifier::NotifyTrackingProtectionDisabled",
|
||||
[self]() {
|
||||
nsChannelClassifier::NotifyTrackingProtectionDisabled(self);
|
||||
}),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::ProcessNotifyTrackingResource()
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessNotifyTrackingResource [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
SetIsTrackingResource();
|
||||
nsCOMPtr<nsIEventTarget> mainTarget = GetMainThreadEventTarget();
|
||||
mainTarget->Dispatch(
|
||||
NewRunnableMethod(
|
||||
"HttpChannelChild::SetIsTrackingResource",
|
||||
this, &HttpChannelChild::SetIsTrackingResource),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1729,22 +1768,36 @@ HttpChannelChild::ProcessSetClassifierMatchedInfo(const nsCString& aList,
|
|||
const nsCString& aPrefix)
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessSetClassifierMatchedInfo [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
|
||||
SetMatchedInfo(aList, aProvider, aPrefix);
|
||||
nsCOMPtr<nsIEventTarget> mainTarget = GetMainThreadEventTarget();
|
||||
mainTarget->Dispatch(
|
||||
NewRunnableMethod<const nsCString, const nsCString, const nsCString>
|
||||
("HttpChannelChild::SetMatchedInfo",
|
||||
this, &HttpChannelChild::SetMatchedInfo,
|
||||
aList, aProvider, aPrefix),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::ProcessDivertMessages()
|
||||
{
|
||||
LOG(("HttpChannelChild::ProcessDivertMessages [this=%p]\n", this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
MOZ_RELEASE_ASSERT(mDivertingToParent);
|
||||
MOZ_RELEASE_ASSERT(mSuspendCount > 0);
|
||||
|
||||
// DivertTo() has been called on parent, so we can now start sending queued
|
||||
// IPDL messages back to parent listener.
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(Resume()));
|
||||
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
|
||||
MOZ_ASSERT(neckoTarget);
|
||||
nsresult rv =
|
||||
neckoTarget->Dispatch(
|
||||
NewRunnableMethod(
|
||||
"HttpChannelChild::Resume",
|
||||
this, &HttpChannelChild::Resume),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
// Returns true if has actually completed the redirect and cleaned up the
|
||||
|
@ -1866,12 +1919,29 @@ HttpChannelChild::ConnectParent(uint32_t registrarId)
|
|||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mBgChildMutex);
|
||||
|
||||
MOZ_ASSERT(!mBgChild);
|
||||
MOZ_ASSERT(!mBgInitFailCallback);
|
||||
|
||||
mBgInitFailCallback = NewRunnableMethod<nsresult>(
|
||||
"HttpChannelChild::OnRedirectVerifyCallback",
|
||||
this, &HttpChannelChild::OnRedirectVerifyCallback,
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> bgChild =
|
||||
new HttpBackgroundChannelChild();
|
||||
|
||||
nsresult rv = bgChild->Init(this);
|
||||
MOZ_RELEASE_ASSERT(gSocketTransportService);
|
||||
|
||||
RefPtr<HttpChannelChild> self = this;
|
||||
nsresult rv =
|
||||
gSocketTransportService->Dispatch(
|
||||
NewRunnableMethod<RefPtr<HttpChannelChild>>(
|
||||
"HttpBackgroundChannelChild::Init",
|
||||
bgChild, &HttpBackgroundChannelChild::Init, Move(self)),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -2102,7 +2172,8 @@ NS_IMETHODIMP
|
|||
HttpChannelChild::Suspend()
|
||||
{
|
||||
LOG(("HttpChannelChild::Suspend [this=%p, mSuspendCount=%" PRIu32 ", "
|
||||
"mDivertingToParent=%d]\n", this, mSuspendCount+1, mDivertingToParent));
|
||||
"mDivertingToParent=%d]\n", this, mSuspendCount + 1,
|
||||
static_cast<bool>(mDivertingToParent)));
|
||||
NS_ENSURE_TRUE(RemoteChannelExists() || mInterceptListener,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
|
@ -2127,7 +2198,8 @@ NS_IMETHODIMP
|
|||
HttpChannelChild::Resume()
|
||||
{
|
||||
LOG(("HttpChannelChild::Resume [this=%p, mSuspendCount=%" PRIu32 ", "
|
||||
"mDivertingToParent=%d]\n", this, mSuspendCount-1, mDivertingToParent));
|
||||
"mDivertingToParent=%d]\n", this, mSuspendCount - 1,
|
||||
static_cast<bool>(mDivertingToParent)));
|
||||
NS_ENSURE_TRUE(RemoteChannelExists() || mInterceptListener,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
|
||||
|
@ -2511,18 +2583,41 @@ HttpChannelChild::ContinueAsyncOpen()
|
|||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mBgChildMutex);
|
||||
|
||||
MOZ_RELEASE_ASSERT(gSocketTransportService);
|
||||
|
||||
// Service worker might use the same HttpChannelChild to do async open
|
||||
// twice. Need to disconnect with previous background channel before
|
||||
// creating the new one.
|
||||
// creating the new one, to prevent receiving further notification
|
||||
// from it.
|
||||
if (mBgChild) {
|
||||
RefPtr<HttpBackgroundChannelChild> prevBgChild = mBgChild.forget();
|
||||
prevBgChild->OnChannelClosed();
|
||||
gSocketTransportService->Dispatch(
|
||||
NewRunnableMethod(
|
||||
"HttpBackgroundChannelChild::OnChannelClosed",
|
||||
prevBgChild, &HttpBackgroundChannelChild::OnChannelClosed),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mBgInitFailCallback);
|
||||
|
||||
mBgInitFailCallback = NewRunnableMethod<nsresult>(
|
||||
"HttpChannelChild::FailedAsyncOpen",
|
||||
this, &HttpChannelChild::FailedAsyncOpen,
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
RefPtr<HttpBackgroundChannelChild> bgChild =
|
||||
new HttpBackgroundChannelChild();
|
||||
|
||||
rv = bgChild->Init(this);
|
||||
RefPtr<HttpChannelChild> self = this;
|
||||
nsresult rv =
|
||||
gSocketTransportService->Dispatch(
|
||||
NewRunnableMethod<RefPtr<HttpChannelChild>>(
|
||||
"HttpBackgroundChannelChild::Init",
|
||||
bgChild, &HttpBackgroundChannelChild::Init, self),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -3115,6 +3210,8 @@ HttpChannelChild::UnknownDecoderInvolvedKeepData()
|
|||
{
|
||||
LOG(("HttpChannelChild::UnknownDecoderInvolvedKeepData [this=%p]",
|
||||
this));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mUnknownDecoderInvolved = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3123,7 +3220,10 @@ NS_IMETHODIMP
|
|||
HttpChannelChild::UnknownDecoderInvolvedOnStartRequestCalled()
|
||||
{
|
||||
LOG(("HttpChannelChild::UnknownDecoderInvolvedOnStartRequestCalled "
|
||||
"[this=%p, mDivertingToParent=%d]", this, mDivertingToParent));
|
||||
"[this=%p, mDivertingToParent=%d]", this,
|
||||
static_cast<bool>(mDivertingToParent)));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mUnknownDecoderInvolved = false;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
// Callback while background channel is ready.
|
||||
void OnBackgroundChildReady(HttpBackgroundChannelChild* aBgChild);
|
||||
// Callback while background channel is destroyed.
|
||||
void OnBackgroundChildDestroyed();
|
||||
void OnBackgroundChildDestroyed(HttpBackgroundChannelChild* aBgChild);
|
||||
|
||||
protected:
|
||||
mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& channelStatus,
|
||||
|
@ -294,13 +294,13 @@ private:
|
|||
// this queue keeps OnDataAvailable data until OnStartRequest is finally
|
||||
// called.
|
||||
nsTArray<UniquePtr<ChannelEvent>> mUnknownDecoderEventQ;
|
||||
bool mUnknownDecoderInvolved;
|
||||
Atomic<bool, ReleaseAcquire> mUnknownDecoderInvolved;
|
||||
|
||||
// Once set, OnData and possibly OnStop will be diverted to the parent.
|
||||
bool mDivertingToParent;
|
||||
Atomic<bool, ReleaseAcquire> mDivertingToParent;
|
||||
// Once set, no OnStart/OnData/OnStop callbacks should be received from the
|
||||
// parent channel, nor dequeued from the ChannelEventQueue.
|
||||
bool mFlushedForDiversion;
|
||||
Atomic<bool, ReleaseAcquire> mFlushedForDiversion;
|
||||
// Set if SendSuspend is called. Determines if SendResume is needed when
|
||||
// diverting callbacks to parent.
|
||||
bool mSuspendSent;
|
||||
|
@ -332,8 +332,15 @@ private:
|
|||
// is synthesized.
|
||||
bool mSuspendParentAfterSynthesizeResponse;
|
||||
|
||||
// Used to ensure atomicity of mBgChild and mBgInitFailCallback
|
||||
Mutex mBgChildMutex;
|
||||
|
||||
// Associated HTTP background channel
|
||||
RefPtr<HttpBackgroundChannelChild> mBgChild;
|
||||
|
||||
// Error handling procedure if failed to establish PBackground IPC
|
||||
nsCOMPtr<nsIRunnable> mBgInitFailCallback;
|
||||
|
||||
// Remove the association with background channel after OnStopRequest
|
||||
// or AsyncAbort.
|
||||
void CleanupBackgroundChannel();
|
||||
|
|
|
@ -4412,7 +4412,7 @@ nsHttpChannel::OnCacheEntryAvailableInternal(nsICacheEntry *entry,
|
|||
|
||||
if (mCanceled) {
|
||||
LOG(("channel was canceled [this=%p status=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(mStatus)));
|
||||
this, static_cast<uint32_t>(static_cast<nsresult>(mStatus))));
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
|
@ -5047,7 +5047,7 @@ nsHttpChannel::CloseCacheEntry(bool doomOnFailure)
|
|||
return;
|
||||
|
||||
LOG(("nsHttpChannel::CloseCacheEntry [this=%p] mStatus=%" PRIx32 " mCacheEntryIsWriteOnly=%x",
|
||||
this, static_cast<uint32_t>(mStatus), mCacheEntryIsWriteOnly));
|
||||
this, static_cast<uint32_t>(static_cast<nsresult>(mStatus)), mCacheEntryIsWriteOnly));
|
||||
|
||||
// If we have begun to create or replace a cache entry, and that cache
|
||||
// entry is not complete and not resumable, then it needs to be doomed.
|
||||
|
@ -6743,7 +6743,8 @@ nsHttpChannel::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
|
|||
{
|
||||
LOG(("nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%" PRIx32
|
||||
" mStatus=%" PRIx32 "]\n",
|
||||
this, pi, static_cast<uint32_t>(status), static_cast<uint32_t>(mStatus)));
|
||||
this, pi, static_cast<uint32_t>(status),
|
||||
static_cast<uint32_t>(static_cast<nsresult>(mStatus))));
|
||||
mProxyRequest = nullptr;
|
||||
|
||||
nsresult rv;
|
||||
|
@ -6967,11 +6968,13 @@ nsHttpChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
|||
if (!(mCanceled || NS_FAILED(mStatus)) && !WRONG_RACING_RESPONSE_SOURCE(request)) {
|
||||
// capture the request's status, so our consumers will know ASAP of any
|
||||
// connection failures, etc - bug 93581
|
||||
request->GetStatus(&mStatus);
|
||||
nsresult status;
|
||||
request->GetStatus(&status);
|
||||
mStatus = status;
|
||||
}
|
||||
|
||||
LOG(("nsHttpChannel::OnStartRequest [this=%p request=%p status=%" PRIx32 "]\n",
|
||||
this, request, static_cast<uint32_t>(mStatus)));
|
||||
this, request, static_cast<uint32_t>(static_cast<nsresult>(mStatus))));
|
||||
|
||||
if (mRaceCacheWithNetwork) {
|
||||
LOG((" racingNetAndCache - mFirstResponseSource:%d fromCache:%d fromNet:%d\n",
|
||||
|
|
Загрузка…
Ссылка в новой задаче