Bug 1643382 - P1: BackgroundDataBridgeChild and HttpBackgroundChannelChild don't need to be a cycle r=dragana

Differential Revision: https://phabricator.services.mozilla.com/D79254
This commit is contained in:
Kershaw Chang
2020-06-18 09:28:33 +00:00
parent 47c29ca063
commit c03bf62590
5 changed files with 35 additions and 25 deletions

View File

@@ -176,6 +176,11 @@ void SocketProcessChild::CleanUp() {
iter.Data()->Close(); iter.Data()->Close();
} }
} }
{
MutexAutoLock lock(mMutex);
mBackgroundDataBridgeMap.Clear();
}
NS_ShutdownXPCOM(nullptr); NS_ShutdownXPCOM(nullptr);
} }

View File

@@ -10,27 +10,27 @@ namespace net {
BackgroundDataBridgeChild::BackgroundDataBridgeChild( BackgroundDataBridgeChild::BackgroundDataBridgeChild(
HttpBackgroundChannelChild* aBgChild) HttpBackgroundChannelChild* aBgChild)
: mBgChild(aBgChild), mBackgroundThread(NS_GetCurrentThread()) { : mBgChild(aBgChild) {
MOZ_ASSERT(aBgChild); MOZ_ASSERT(aBgChild);
} }
BackgroundDataBridgeChild::~BackgroundDataBridgeChild() = default; BackgroundDataBridgeChild::~BackgroundDataBridgeChild() = default;
void BackgroundDataBridgeChild::Destroy() { void BackgroundDataBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
RefPtr<BackgroundDataBridgeChild> self = this; mBgChild = nullptr;
MOZ_ALWAYS_SUCCEEDS(mBackgroundThread->Dispatch(
NS_NewRunnableFunction("BackgroundDataBridgeParent::Destroy",
[self]() {
if (self->CanSend()) {
Unused << self->Send__delete__(self);
}
}),
NS_DISPATCH_NORMAL));
} }
mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnTransportAndData( mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnTransportAndData(
const uint64_t& offset, const uint32_t& count, const nsCString& data) { const uint64_t& offset, const uint32_t& count, const nsCString& data) {
MOZ_ASSERT(mBgChild); if (!mBgChild) {
return IPC_OK();
}
if (mBgChild->ChannelClosed()) {
Unused << Send__delete__(this);
return IPC_OK();
}
return mBgChild->RecvOnTransportAndData(NS_OK, NS_NET_STATUS_RECEIVING_FROM, return mBgChild->RecvOnTransportAndData(NS_OK, NS_NET_STATUS_RECEIVING_FROM,
offset, count, data, true); offset, count, data, true);
} }

View File

@@ -17,13 +17,12 @@ class BackgroundDataBridgeChild final : public PBackgroundDataBridgeChild {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundDataBridgeChild, override) NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundDataBridgeChild, override)
explicit BackgroundDataBridgeChild(HttpBackgroundChannelChild* aBgChild); explicit BackgroundDataBridgeChild(HttpBackgroundChannelChild* aBgChild);
void Destroy();
protected: protected:
virtual ~BackgroundDataBridgeChild(); virtual ~BackgroundDataBridgeChild();
void ActorDestroy(ActorDestroyReason aWhy) override;
RefPtr<HttpBackgroundChannelChild> mBgChild; RefPtr<HttpBackgroundChannelChild> mBgChild;
nsCOMPtr<nsIThread> mBackgroundThread;
public: public:
mozilla::ipc::IPCResult RecvOnTransportAndData(const uint64_t& offset, mozilla::ipc::IPCResult RecvOnTransportAndData(const uint64_t& offset,

View File

@@ -49,17 +49,21 @@ nsresult HttpBackgroundChannelChild::Init(HttpChannelChild* aChannelChild) {
void HttpBackgroundChannelChild::CreateDataBridge() { void HttpBackgroundChannelChild::CreateDataBridge() {
MOZ_ASSERT(OnSocketThread()); MOZ_ASSERT(OnSocketThread());
if (!mChannelChild) {
return;
}
PBackgroundChild* actorChild = PBackgroundChild* actorChild =
BackgroundChild::GetOrCreateSocketActorForCurrentThread(); BackgroundChild::GetOrCreateSocketActorForCurrentThread();
if (NS_WARN_IF(!actorChild)) { if (NS_WARN_IF(!actorChild)) {
return; return;
} }
mDataBridgeChild = new BackgroundDataBridgeChild(this); RefPtr<BackgroundDataBridgeChild> dataBridgeChild =
if (!actorChild->SendPBackgroundDataBridgeConstructor( new BackgroundDataBridgeChild(this);
mDataBridgeChild, mChannelChild->ChannelId())) { Unused << actorChild->SendPBackgroundDataBridgeConstructor(
mDataBridgeChild = nullptr; dataBridgeChild, mChannelChild->ChannelId());
}
} }
void HttpBackgroundChannelChild::OnChannelClosed() { void HttpBackgroundChannelChild::OnChannelClosed() {
@@ -71,11 +75,12 @@ void HttpBackgroundChannelChild::OnChannelClosed() {
// Remove pending IPC messages as well. // Remove pending IPC messages as well.
mQueuedRunnables.Clear(); mQueuedRunnables.Clear();
}
if (mDataBridgeChild) { bool HttpBackgroundChannelChild::ChannelClosed() {
mDataBridgeChild->Destroy(); MOZ_ASSERT(OnSocketThread());
mDataBridgeChild = nullptr;
} return !mChannelChild;
} }
void HttpBackgroundChannelChild::OnStartRequestReceived() { void HttpBackgroundChannelChild::OnStartRequestReceived() {

View File

@@ -39,6 +39,9 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
// handle any incoming messages over background channel. // handle any incoming messages over background channel.
void OnChannelClosed(); void OnChannelClosed();
// Return true if OnChannelClosed has been called.
bool ChannelClosed();
// Callback when OnStartRequest is received and handled by HttpChannelChild. // Callback when OnStartRequest is received and handled by HttpChannelChild.
// Enqueued messages in background channel will be flushed. // Enqueued messages in background channel will be flushed.
void OnStartRequestReceived(); void OnStartRequestReceived();
@@ -110,8 +113,6 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
// Should be flushed after OnStartRequest is received and handled. // Should be flushed after OnStartRequest is received and handled.
// Should only access on STS thread. // Should only access on STS thread.
nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables; nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
RefPtr<BackgroundDataBridgeChild> mDataBridgeChild;
}; };
} // namespace net } // namespace net