Bug 838616 - Eliminate a process-priority race condition around preallocated process creation. r=cjones

Previously, it was possible to return a dead preallocated process.  This
patch eliminates or at least significantly reduces the likelihood of
this race.

--HG--
extra : rebase_source : f51022581edbdee8b72a8a56e296b6706bf1d165
This commit is contained in:
Justin Lebar 2013-02-08 14:32:23 +00:00
parent 7cd213655c
commit a7e9aa2948
2 changed files with 32 additions and 10 deletions

View File

@ -251,10 +251,26 @@ ContentParent::ScheduleDelayedPreallocateAppProcess()
}
/*static*/ already_AddRefed<ContentParent>
ContentParent::MaybeTakePreallocatedAppProcess()
ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
ChildPrivileges aPrivs)
{
nsRefPtr<ContentParent> process = sPreallocatedAppProcess.get();
sPreallocatedAppProcess = nullptr;
if (!process) {
return nullptr;
}
if (!process->TransformPreallocatedIntoApp(aAppManifestURL, aPrivs)) {
NS_WARNING("Can't TransformPrealocatedIntoApp. Maybe "
"the preallocated process died?");
// Kill the process just in case it's not actually dead; we don't want
// to "leak" this process!
process->KillHard();
return nullptr;
}
return process.forget();
}
@ -443,10 +459,8 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext)
nsRefPtr<ContentParent> p = gAppContentParents->Get(manifestURL);
if (!p) {
ChildPrivileges privs = PrivilegesForApp(ownApp);
p = MaybeTakePreallocatedAppProcess();
if (p) {
p->TransformPreallocatedIntoApp(manifestURL, privs);
} else {
p = MaybeTakePreallocatedAppProcess(manifestURL, privs);
if (!p) {
NS_WARNING("Unable to use pre-allocated app process");
p = new ContentParent(manifestURL, /* isBrowserElement = */ false,
privs);
@ -532,7 +546,7 @@ ContentParent::Init()
NS_ASSERTION(observer, "FileUpdateDispatcher is null");
}
void
bool
ContentParent::TransformPreallocatedIntoApp(const nsAString& aAppManifestURL,
ChildPrivileges aPrivs)
{
@ -551,7 +565,7 @@ ContentParent::TransformPreallocatedIntoApp(const nsAString& aAppManifestURL,
}
// If this fails, the child process died.
unused << SendSetProcessPrivileges(aPrivs);
return SendSetProcessPrivileges(aPrivs);
}
void

View File

@ -158,7 +158,14 @@ private:
static void PreallocateAppProcess();
static void DelayedPreallocateAppProcess();
static void ScheduleDelayedPreallocateAppProcess();
static already_AddRefed<ContentParent> MaybeTakePreallocatedAppProcess();
// Take the preallocated process and transform it into a "real" app process,
// for the specified manifest URL. If there is no preallocated process (or
// if it's dead), this returns false.
static already_AddRefed<ContentParent>
MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
ChildPrivileges aPrivs);
static void FirstIdle();
// Hide the raw constructor methods since we don't want client code
@ -173,8 +180,9 @@ private:
void Init();
// Transform a pre-allocated app process into a "real" app
// process, for the specified manifest URL.
void TransformPreallocatedIntoApp(const nsAString& aAppManifestURL,
// process, for the specified manifest URL. If this returns false, the
// child process has died.
bool TransformPreallocatedIntoApp(const nsAString& aAppManifestURL,
ChildPrivileges aPrivs);
/**