Skip to content

Commit

Permalink
Bug 1192255: Clean up ContentParent's observer topics for the Nuwa pr…
Browse files Browse the repository at this point in the history
…ocess. r=khuey

--HG--
extra : rebase_source : 8350c348f79459ad04453be6a02b7c66a4e04b0a
  • Loading branch information
Cervantes Yu committed Aug 14, 2015
1 parent 87e54b9 commit 2c8c57b
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 55 deletions.
11 changes: 2 additions & 9 deletions dom/ipc/ContentChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2174,10 +2174,7 @@ bool
ContentChild::RecvFlushMemory(const nsString& reason)
{
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess()) {
// Don't flush memory in the nuwa process: the GC thread could be frozen.
return true;
}
MOZ_ASSERT(!IsNuwaProcess() || !IsNuwaReady());
#endif
nsCOMPtr<nsIObserverService> os =
mozilla::services::GetObserverService();
Expand Down Expand Up @@ -2416,11 +2413,7 @@ bool
ContentChild::RecvMinimizeMemoryUsage()
{
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess()) {
// Don't minimize memory in the nuwa process: it will perform GC, but the
// GC thread could be frozen.
return true;
}
MOZ_ASSERT(!IsNuwaProcess() || !IsNuwaReady());
#endif
nsCOMPtr<nsIMemoryReporterManager> mgr =
do_GetService("@mozilla.org/memory-reporter-manager;1");
Expand Down
125 changes: 79 additions & 46 deletions dom/ipc/ContentParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,22 @@ static const char* sObserverTopics[] = {
#endif
};

#ifdef MOZ_NUWA_PROCESS
// Contains the observer topics that can be sent to the Nuwa process after it
// becomes ready. The ContentParent instance will unregister sObserverTopics
// if not listed in sNuwaSafeObserverTopics.
static const char* sNuwaSafeObserverTopics[] = {
"xpcom-shutdown",
"profile-before-change",
#ifdef MOZ_WIDGET_GONK
"phone-state-changed",
#endif
#ifdef ACCESSIBILITY
"a11y-init-or-shutdown",
#endif
"nsPref:Changed"
};
#endif
/* static */ already_AddRefed<ContentParent>
ContentParent::RunNuwaProcess()
{
Expand Down Expand Up @@ -2923,6 +2939,41 @@ ContentParent::ForkNewProcess(bool aBlocking)
#endif
}

#ifdef MOZ_NUWA_PROCESS
// Keep only observer topics listed in sNuwaSafeObserverTopics and unregister
// all the other registered topics.
static void
KeepNuwaSafeObserverTopics(ContentParent* aNuwaContentParent)
{
MOZ_ASSERT(aNuwaContentParent && aNuwaContentParent->IsNuwaProcess());

nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
return;
}

size_t topicLength = ArrayLength(sObserverTopics);
for (size_t i = 0; i < topicLength; ++i) {
bool nuwaSafe = false;
size_t safeTopicLength = ArrayLength(sNuwaSafeObserverTopics);

for (size_t j = 0; j < safeTopicLength; j++) {
if (!nsCRT::strcmp(sObserverTopics[i],
sNuwaSafeObserverTopics[j])) {
// In the whitelist: don't need to unregister.
nuwaSafe = true;
break;
}
}

if (!nuwaSafe) {
obs->RemoveObserver(aNuwaContentParent, sObserverTopics[i]);
}
}

}
#endif

void
ContentParent::OnNuwaReady()
{
Expand All @@ -2932,6 +2983,8 @@ ContentParent::OnNuwaReady()
MOZ_ASSERT(IsNuwaProcess());

sNuwaReady = true;
KeepNuwaSafeObserverTopics(this);

PreallocatedProcessManager::OnNuwaReady();
return;
#else
Expand Down Expand Up @@ -3025,6 +3078,16 @@ ContentParent::Observe(nsISupports* aSubject,
if (!mIsAlive || !mSubprocess)
return NS_OK;

// The Nuwa process unregisters the topics after it becomes ready except for
// the ones listed in sNuwaSafeObserverTopics. If the topic needs to be
// observed by the Nuwa process, either for:
// 1. The topic is safe for the Nuwa process, either:
// 1.1 The state can safely happen (only run on the main thread) in the Nuwa
// process (e.g. "a11y-init-or-shutdown"), or
// 1.2 The topic doesn't send an IPC message (e.g. "xpcom-shutdown").
// 2. The topic needs special handling (e.g. nsPref:Changed),
// add the topic to sNuwaSafeObserverTopics and then handle it if necessary.

// listening for memory pressure event
if (!strcmp(aTopic, "memory-pressure") &&
!StringEndsWith(nsDependentString(aData),
Expand All @@ -3039,7 +3102,7 @@ ContentParent::Observe(nsISupports* aSubject,
PrefSetting pref(strData, null_t(), null_t());
Preferences::GetPreference(&pref);
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess() && PreallocatedProcessManager::IsNuwaReady()) {
if (IsReadyNuwaProcess()) {
// Don't send the pref update to the Nuwa process. Save the update
// to send to the forked child.
if (!sNuwaPrefUpdates) {
Expand All @@ -3056,28 +3119,16 @@ ContentParent::Observe(nsISupports* aSubject,
#endif
}
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
NS_ConvertUTF16toUTF8 dataStr(aData);
const char *offline = dataStr.get();
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess())) {
#endif
if (!SendSetOffline(!strcmp(offline, "true") ? true : false)) {
return NS_ERROR_NOT_AVAILABLE;
}
#ifdef MOZ_NUWA_PROCESS
}
#endif
NS_ConvertUTF16toUTF8 dataStr(aData);
const char *offline = dataStr.get();
if (!SendSetOffline(!strcmp(offline, "true") ? true : false)) {
return NS_ERROR_NOT_AVAILABLE;
}
}
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC)) {
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess())) {
#endif
if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
return NS_ERROR_NOT_AVAILABLE;
}
#ifdef MOZ_NUWA_PROCESS
if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
return NS_ERROR_NOT_AVAILABLE;
}
#endif
}
// listening for alert notifications
else if (!strcmp(aTopic, "alertfinished") ||
Expand All @@ -3103,13 +3154,7 @@ ContentParent::Observe(nsISupports* aSubject,
nsCString creason;
CopyUTF16toUTF8(aData, creason);
DeviceStorageFile* file = static_cast<DeviceStorageFile*>(aSubject);

#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess()))
#endif
{
unused << SendFilePathUpdate(file->mStorageType, file->mStorageName, file->mPath, creason);
}
unused << SendFilePathUpdate(file->mStorageType, file->mStorageName, file->mPath, creason);
}
#ifdef MOZ_WIDGET_GONK
else if(!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) {
Expand Down Expand Up @@ -3142,27 +3187,17 @@ ContentParent::Observe(nsISupports* aSubject,
vol->GetIsRemovable(&isRemovable);
vol->GetIsHotSwappable(&isHotSwappable);

#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess()))
#endif
{
unused << SendFileSystemUpdate(volName, mountPoint, state,
mountGeneration, isMediaPresent,
isSharing, isFormatting, isFake,
isUnmounting, isRemovable, isHotSwappable);
}
unused << SendFileSystemUpdate(volName, mountPoint, state,
mountGeneration, isMediaPresent,
isSharing, isFormatting, isFake,
isUnmounting, isRemovable, isHotSwappable);
} else if (!strcmp(aTopic, "phone-state-changed")) {
nsString state(aData);
unused << SendNotifyPhoneStateChange(state);
}
else if(!strcmp(aTopic, NS_VOLUME_REMOVED)) {
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess()))
#endif
{
nsString volName(aData);
unused << SendVolumeRemoved(volName);
}
nsString volName(aData);
unused << SendVolumeRemoved(volName);
}
#endif
#ifdef ACCESSIBILITY
Expand Down Expand Up @@ -4468,12 +4503,10 @@ ContentParent::DoSendAsyncMessage(JSContext* aCx,
if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
return false;
}
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess() && IsNuwaReady()) {
if (IsReadyNuwaProcess()) {
// Nuwa won't receive frame messages after it is frozen.
return true;
}
#endif
return SendAsyncMessage(nsString(aMessage), data, cpows, Principal(aPrincipal));
}

Expand Down
9 changes: 9 additions & 0 deletions dom/ipc/ContentParent.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,15 @@ class ContentParent final : public PContentParent
bool IsNuwaProcess();
#endif

// A shorthand for checking if the Nuwa process is ready.
bool IsReadyNuwaProcess() {
#ifdef MOZ_NUWA_PROCESS
return IsNuwaProcess() && IsNuwaReady();
#else
return false;
#endif
}

GeckoChildProcessHost* Process() {
return mSubprocess;
}
Expand Down
1 change: 1 addition & 0 deletions ipc/glue/MessageLink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ ProcessLink::SendMessage(Message *msg)
case mozilla::dom::PNuwa::Msg_Fork__ID:
case mozilla::dom::PNuwa::Reply_AddNewProcess__ID:
case mozilla::dom::PContent::Msg_NotifyPhoneStateChange__ID:
case mozilla::dom::PContent::Msg_ActivateA11y__ID:
case mozilla::hal_sandbox::PHal::Msg_NotifyNetworkChange__ID:
case GOODBYE_MESSAGE_TYPE:
break;
Expand Down

0 comments on commit 2c8c57b

Please sign in to comment.