Bug 1513057 - P9: socket oepration should wait until socket process launch r=mayhemer,dragana,kershaw

Differential Revision: https://phabricator.services.mozilla.com/D14510

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kershaw Chang 2019-01-11 14:23:19 +00:00
parent 562055d29e
commit db8c311487
3 changed files with 60 additions and 8 deletions

View File

@ -192,6 +192,7 @@ nsIOService::nsIOService()
mOfflineMirrorsConnectivity(true),
mSettingOffline(false),
mSetOfflineValue(false),
mSocketProcessLaunchComplete(false),
mShutdown(false),
mHttpHandlerAlreadyShutingDown(false),
mNetworkLinkServiceInitialized(false),
@ -441,14 +442,16 @@ bool nsIOService::SocketProcessReady() {
void nsIOService::NotifySocketProcessPrefsChanged(const char *aName) {
MOZ_ASSERT(NS_IsMainThread());
if (!SocketProcessReady()) {
mQueuedPrefNames.AppendElement(aName);
if (!XRE_IsParentProcess()) {
return;
}
dom::Pref pref(nsCString(aName), /* isLocked */ false, null_t(), null_t());
Preferences::GetPreference(&pref);
Unused << mSocketProcess->GetActor()->SendPreferenceUpdate(pref);
auto sendPrefUpdate = [pref]() {
Unused << gIOService->mSocketProcess->GetActor()->SendPreferenceUpdate(pref);
};
CallOrWaitForSocketProcess(sendPrefUpdate);
}
void nsIOService::OnProcessLaunchComplete(SocketProcessHost *aHost,
@ -456,10 +459,34 @@ void nsIOService::OnProcessLaunchComplete(SocketProcessHost *aHost,
MOZ_ASSERT(NS_IsMainThread());
LOG(("nsIOService::OnProcessLaunchComplete aSucceeded=%d\n", aSucceeded));
for (auto name : mQueuedPrefNames) {
NotifySocketProcessPrefsChanged(name);
mSocketProcessLaunchComplete = true;
if (mShutdown || !SocketProcessReady()) {
return;
}
mQueuedPrefNames.Clear();
if (!mPendingEvents.IsEmpty()) {
nsTArray<std::function<void()>> pendingEvents;
mPendingEvents.SwapElements(pendingEvents);
for (auto& func : pendingEvents) {
func();
}
}
}
void nsIOService::CallOrWaitForSocketProcess(const std::function<void()>& aFunc) {
MOZ_ASSERT(NS_IsMainThread());
if (IsSocketProcessLaunchComplete() && SocketProcessReady()) {
aFunc();
} else {
mPendingEvents.AppendElement(aFunc); // infallible
}
}
bool nsIOService::IsSocketProcessLaunchComplete() {
MOZ_ASSERT(NS_IsMainThread());
return mSocketProcessLaunchComplete;
}
void nsIOService::OnProcessUnexpectedShutdown(SocketProcessHost *aHost) {
@ -1383,7 +1410,10 @@ nsIOService::Observe(nsISupports *subject, const char *topic,
SetOffline(false);
}
} else if (!strcmp(topic, kProfileDoChange)) {
if (data && NS_LITERAL_STRING("startup").Equals(data)) {
if (!data) {
return NS_OK;
}
if (NS_LITERAL_STRING("startup").Equals(data)) {
// Lazy initialization of network link service (see bug 620472)
InitializeNetworkLinkService();
// Set up the initilization flag regardless the actuall result.
@ -1398,6 +1428,9 @@ nsIOService::Observe(nsISupports *subject, const char *topic,
// before something calls into the cookie service.
nsCOMPtr<nsISupports> cookieServ =
do_GetService(NS_COOKIESERVICE_CONTRACTID);
} else if (NS_LITERAL_STRING("xpcshell-do-get-profile").Equals(data)) {
// xpcshell doesn't read user profile.
LaunchSocketProcess();
}
} else if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
// Remember we passed XPCOM shutdown notification to prevent any

View File

@ -121,6 +121,13 @@ class nsIOService final : public nsIIOService,
bool SocketProcessReady();
void NotifySocketProcessPrefsChanged(const char* aName);
bool IsSocketProcessLaunchComplete();
// Call func immediately if socket process is launched completely. Otherwise,
// |func| will be queued and then executed in the *main thread* once socket
// process is launced.
void CallOrWaitForSocketProcess(const std::function<void()>& aFunc);
friend SocketProcessMemoryReporter;
RefPtr<MemoryReportingProcess> GetSocketProcessMemoryReporter();
@ -190,6 +197,8 @@ class nsIOService final : public nsIIOService,
bool mSettingOffline;
bool mSetOfflineValue;
bool mSocketProcessLaunchComplete;
mozilla::Atomic<bool, mozilla::Relaxed> mShutdown;
mozilla::Atomic<bool, mozilla::Relaxed> mHttpHandlerAlreadyShutingDown;
@ -229,7 +238,11 @@ class nsIOService final : public nsIIOService,
mozilla::Atomic<PRIntervalTime> mNetTearingDownStarted;
SocketProcessHost* mSocketProcess;
nsTArray<const char*> mQueuedPrefNames;
// Events should be executed after the socket process is launched. Will
// dispatch these events while socket process fires OnProcessLaunchComplete.
// Note: this array is accessed only on the main thread.
nsTArray<std::function<void()>> mPendingEvents;
public:
// Used for all default buffer sizes that necko allocates.

View File

@ -28,6 +28,7 @@ class OfflineObserver final : public nsIObserver {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->AddObserver(this, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC, false);
obs->AddObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, false);
}
}
@ -58,6 +59,11 @@ class OfflineObserver final : public nsIObserver {
!strcmp(offline, "true") ? true : false)) {
return NS_ERROR_NOT_AVAILABLE;
}
} else if (!strcmp(aTopic, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID)) {
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
obs->RemoveObserver(this, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC);
obs->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
}
return NS_OK;