зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1677632 - pt1 - restart the socket process after a crash. r=kershaw,necko-reviewers
This will restart the socket process with a tab refresh or opening a new tab. Differential Revision: https://phabricator.services.mozilla.com/D102481
This commit is contained in:
Родитель
2ff56dfe72
Коммит
98cf76a718
|
@ -28,7 +28,10 @@ MediaTransportHandlerIPC::MediaTransportHandlerIPC(
|
|||
const RefPtr<net::SocketProcessBridgeChild>& aBridge) {
|
||||
ipc::PBackgroundChild* actor =
|
||||
ipc::BackgroundChild::GetOrCreateSocketActorForCurrentThread();
|
||||
if (!actor) {
|
||||
// An actor that can't send is possible if the socket process has
|
||||
// crashed but hasn't been reconnected properly. See
|
||||
// SocketProcessBridgeChild::ActorDestroy for more info.
|
||||
if (!actor || !actor->CanSend()) {
|
||||
NS_WARNING(
|
||||
"MediaTransportHandlerIPC async init failed! Webrtc networking "
|
||||
"will not work!");
|
||||
|
|
|
@ -71,7 +71,6 @@ void NeckoChild::InitNeckoChild() {
|
|||
}
|
||||
gNeckoChild = cpc->SendPNeckoConstructor();
|
||||
NS_ASSERTION(gNeckoChild, "PNecko Protocol init failed!");
|
||||
SocketProcessBridgeChild::GetSocketProcessBridge();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -829,35 +829,50 @@ mozilla::ipc::IPCResult NeckoParent::RecvInitSocketProcessBridge(
|
|||
InitSocketProcessBridgeResolver&& aResolver) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
Endpoint<PSocketProcessBridgeChild> invalidEndpoint;
|
||||
if (NS_WARN_IF(mSocketProcessBridgeInited)) {
|
||||
aResolver(std::move(invalidEndpoint));
|
||||
return IPC_OK();
|
||||
}
|
||||
// Initing the socket process bridge must be async here in order to
|
||||
// wait for the socket process launch before executing.
|
||||
auto task = [self = this, resolver = std::move(aResolver)]() {
|
||||
Endpoint<PSocketProcessBridgeChild> invalidEndpoint;
|
||||
if (NS_WARN_IF(self->mSocketProcessBridgeInited)) {
|
||||
resolver(std::move(invalidEndpoint));
|
||||
return;
|
||||
}
|
||||
|
||||
SocketProcessParent* parent = SocketProcessParent::GetSingleton();
|
||||
if (NS_WARN_IF(!parent)) {
|
||||
aResolver(std::move(invalidEndpoint));
|
||||
return IPC_OK();
|
||||
}
|
||||
SocketProcessParent* parent = SocketProcessParent::GetSingleton();
|
||||
if (NS_WARN_IF(!parent)) {
|
||||
resolver(std::move(invalidEndpoint));
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint<PSocketProcessBridgeParent> parentEndpoint;
|
||||
Endpoint<PSocketProcessBridgeChild> childEndpoint;
|
||||
if (NS_WARN_IF(NS_FAILED(PSocketProcessBridge::CreateEndpoints(
|
||||
parent->OtherPid(), Manager()->OtherPid(), &parentEndpoint,
|
||||
&childEndpoint)))) {
|
||||
aResolver(std::move(invalidEndpoint));
|
||||
return IPC_OK();
|
||||
}
|
||||
Endpoint<PSocketProcessBridgeParent> parentEndpoint;
|
||||
Endpoint<PSocketProcessBridgeChild> childEndpoint;
|
||||
if (NS_WARN_IF(NS_FAILED(PSocketProcessBridge::CreateEndpoints(
|
||||
parent->OtherPid(), self->Manager()->OtherPid(), &parentEndpoint,
|
||||
&childEndpoint)))) {
|
||||
resolver(std::move(invalidEndpoint));
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!parent->SendInitSocketProcessBridgeParent(
|
||||
Manager()->OtherPid(), std::move(parentEndpoint)))) {
|
||||
aResolver(std::move(invalidEndpoint));
|
||||
return IPC_OK();
|
||||
}
|
||||
if (NS_WARN_IF(!parent->SendInitSocketProcessBridgeParent(
|
||||
self->Manager()->OtherPid(), std::move(parentEndpoint)))) {
|
||||
resolver(std::move(invalidEndpoint));
|
||||
return;
|
||||
}
|
||||
|
||||
aResolver(std::move(childEndpoint));
|
||||
mSocketProcessBridgeInited = true;
|
||||
resolver(std::move(childEndpoint));
|
||||
self->mSocketProcessBridgeInited = true;
|
||||
};
|
||||
gIOService->CallOrWaitForSocketProcess(std::move(task));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult NeckoParent::RecvResetSocketProcessBridge() {
|
||||
// SendResetSocketProcessBridge is called from
|
||||
// SocketProcessBridgeChild::ActorDestroy if the socket process
|
||||
// crashes. This is necessary in order to properly initialize the
|
||||
// restarted socket process.
|
||||
mSocketProcessBridgeInited = false;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -241,6 +241,7 @@ class NeckoParent : public PNeckoParent {
|
|||
|
||||
mozilla::ipc::IPCResult RecvInitSocketProcessBridge(
|
||||
InitSocketProcessBridgeResolver&& aResolver);
|
||||
mozilla::ipc::IPCResult RecvResetSocketProcessBridge();
|
||||
|
||||
mozilla::ipc::IPCResult RecvEnsureHSTSData(
|
||||
EnsureHSTSDataResolver&& aResolver);
|
||||
|
|
|
@ -147,6 +147,7 @@ parent:
|
|||
|
||||
async InitSocketProcessBridge()
|
||||
returns (Endpoint<PSocketProcessBridgeChild> endpoint);
|
||||
async ResetSocketProcessBridge();
|
||||
|
||||
async EnsureHSTSData()
|
||||
returns (bool result);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "SocketProcessLogging.h"
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -151,6 +152,24 @@ mozilla::ipc::IPCResult SocketProcessBridgeChild::RecvTest() {
|
|||
|
||||
void SocketProcessBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
LOG(("SocketProcessBridgeChild::ActorDestroy\n"));
|
||||
if (gNeckoChild) {
|
||||
// Let NeckoParent know that the socket process connections must be
|
||||
// rebuilt.
|
||||
gNeckoChild->SendResetSocketProcessBridge();
|
||||
}
|
||||
nsresult res;
|
||||
nsCOMPtr<nsISerialEventTarget> mSTSThread =
|
||||
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &res);
|
||||
if (NS_SUCCEEDED(res) && mSTSThread) {
|
||||
// This must be called off the main thread. If we don't make this call
|
||||
// ipc::BackgroundChild::GetOrCreateSocketActorForCurrentThread() will
|
||||
// return the previous actor that is no longer able to send. This causes
|
||||
// rebuilding the socket process connections to fail.
|
||||
MOZ_ALWAYS_SUCCEEDS(mSTSThread->Dispatch(NS_NewRunnableFunction(
|
||||
"net::SocketProcessBridgeChild::ActorDestroy",
|
||||
[]() { ipc::BackgroundChild::CloseForCurrentThread(); })));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->RemoveObserver(this, "content-child-shutdown");
|
||||
|
|
Загрузка…
Ссылка в новой задаче