mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-04 11:26:09 +00:00
Bug 773998: Shut down app processes when the last browser closes. r=jlebar
This commit is contained in:
parent
1eff2f94df
commit
02fcf66f8e
@ -251,6 +251,49 @@ ContentParent::Init()
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::ShutDown()
|
||||
{
|
||||
if (mIsAlive) {
|
||||
// Close() can only be called once. It kicks off the
|
||||
// destruction sequence.
|
||||
Close();
|
||||
}
|
||||
// NB: must MarkAsDead() here so that this isn't accidentally
|
||||
// returned from Get*() while in the midst of shutdown.
|
||||
MarkAsDead();
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::MarkAsDead()
|
||||
{
|
||||
if (!mAppManifestURL.IsEmpty()) {
|
||||
if (gAppContentParents) {
|
||||
gAppContentParents->Remove(mAppManifestURL);
|
||||
if (!gAppContentParents->Count()) {
|
||||
delete gAppContentParents;
|
||||
gAppContentParents = NULL;
|
||||
}
|
||||
}
|
||||
} else if (gNonAppContentParents) {
|
||||
gNonAppContentParents->RemoveElement(this);
|
||||
if (!gNonAppContentParents->Length()) {
|
||||
delete gNonAppContentParents;
|
||||
gNonAppContentParents = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (gPrivateContent) {
|
||||
gPrivateContent->RemoveElement(this);
|
||||
if (!gPrivateContent->Length()) {
|
||||
delete gPrivateContent;
|
||||
gPrivateContent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mIsAlive = false;
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::OnChannelConnected(int32 pid)
|
||||
{
|
||||
@ -349,29 +392,7 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
if (mRunToCompletionDepth)
|
||||
mRunToCompletionDepth = 0;
|
||||
|
||||
if (!mAppManifestURL.IsEmpty()) {
|
||||
gAppContentParents->Remove(mAppManifestURL);
|
||||
if (!gAppContentParents->Count()) {
|
||||
delete gAppContentParents;
|
||||
gAppContentParents = NULL;
|
||||
}
|
||||
} else {
|
||||
gNonAppContentParents->RemoveElement(this);
|
||||
if (!gNonAppContentParents->Length()) {
|
||||
delete gNonAppContentParents;
|
||||
gNonAppContentParents = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (gPrivateContent) {
|
||||
gPrivateContent->RemoveElement(this);
|
||||
if (!gPrivateContent->Length()) {
|
||||
delete gPrivateContent;
|
||||
gPrivateContent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mIsAlive = false;
|
||||
MarkAsDead();
|
||||
|
||||
if (obs) {
|
||||
nsRefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
|
||||
@ -416,6 +437,19 @@ ContentParent::CreateTab(PRUint32 aChromeFlags, bool aIsBrowserFrame)
|
||||
return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags, aIsBrowserFrame));
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::NotifyTabDestroyed(PBrowserParent* aTab)
|
||||
{
|
||||
// There can be more than one PBrowser for a given app process
|
||||
// because of popup windows. When the last one closes, shut
|
||||
// us down.
|
||||
if (IsForApp() && ManagedPBrowserParent().Length() == 1) {
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &ContentParent::ShutDown));
|
||||
}
|
||||
}
|
||||
|
||||
TestShellParent*
|
||||
ContentParent::CreateTestShell()
|
||||
{
|
||||
@ -493,6 +527,12 @@ ContentParent::IsAlive()
|
||||
return mIsAlive;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::IsForApp()
|
||||
{
|
||||
return !mAppManifestURL.IsEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvReadPrefsArray(InfallibleTArray<PrefTuple> *prefs)
|
||||
{
|
||||
|
@ -68,6 +68,8 @@ public:
|
||||
* <iframe mozbrowser>.
|
||||
*/
|
||||
TabParent* CreateTab(PRUint32 aChromeFlags, bool aIsBrowserFrame);
|
||||
/** Notify that a tab was destroyed during normal operation. */
|
||||
void NotifyTabDestroyed(PBrowserParent* aTab);
|
||||
|
||||
TestShellParent* CreateTestShell();
|
||||
bool DestroyTestShell(TestShellParent* aTestShell);
|
||||
@ -77,6 +79,7 @@ public:
|
||||
bool RequestRunToCompletion();
|
||||
|
||||
bool IsAlive();
|
||||
bool IsForApp();
|
||||
|
||||
void SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report);
|
||||
|
||||
@ -107,6 +110,20 @@ private:
|
||||
|
||||
void Init();
|
||||
|
||||
/**
|
||||
* Mark this ContentParent as dead for the purposes of Get*().
|
||||
* This method is idempotent.
|
||||
*/
|
||||
void MarkAsDead();
|
||||
|
||||
/**
|
||||
* Exit the subprocess and vamoose. After this call IsAlive()
|
||||
* will return false and this ContentParent will not be returned
|
||||
* by the Get*() funtions. However, the shutdown sequence itself
|
||||
* may be asynchronous.
|
||||
*/
|
||||
void ShutDown();
|
||||
|
||||
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame);
|
||||
virtual bool DeallocPBrowser(PBrowserParent* frame);
|
||||
|
||||
|
@ -99,6 +99,14 @@ TabParent::Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::Recv__delete__()
|
||||
{
|
||||
ContentParent* cp = static_cast<ContentParent*>(Manager());
|
||||
cp->NotifyTabDestroyed(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TabParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
|
@ -164,7 +164,9 @@ protected:
|
||||
const nsString& aJSON,
|
||||
InfallibleTArray<nsString>* aJSONRetVal = nsnull);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason why);
|
||||
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
|
||||
virtual PIndexedDBParent* AllocPIndexedDB(const nsCString& aASCIIOrigin,
|
||||
bool* /* aAllowed */);
|
||||
|
Loading…
Reference in New Issue
Block a user