Bug 774131, part 2: Add GeckoChildProcessHost::LaunchAndWaitForProcessHandle() to do that, use it in ContentParent, and share more process-launching code. r=bent

This commit is contained in:
Chris Jones 2012-08-07 16:29:32 -07:00
parent 7f0f2140b3
commit 0dd87e66bc
3 changed files with 67 additions and 28 deletions

View File

@ -489,13 +489,9 @@ ContentParent::ContentParent(const nsAString& aAppManifestURL)
bool useOffMainThreadCompositing = !!CompositorParent::CompositorLoop();
if (useOffMainThreadCompositing) {
// FIXME. Oh please fixme. Somehow.
//
// We need the child process's ProcessHandle to do
// PCompositor::Open() below (on win32 ... sigh). We don't
// get that until onconnect, but that's too late to open the
// compositor channel below.
mSubprocess->SyncLaunch();
// We need the subprocess's ProcessHandle to create the
// PCompositor channel below. Block just until we have that.
mSubprocess->LaunchAndWaitForProcessHandle();
} else {
mSubprocess->AsyncLaunch();
}

View File

@ -238,6 +238,20 @@ uint32 GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProce
return base::GetCurrentProcessArchitecture();
}
void
GeckoChildProcessHost::PrepareLaunch()
{
#ifdef MOZ_CRASHREPORTER
if (CrashReporter::GetEnabled()) {
CrashReporter::OOPInit();
}
#endif
#ifdef XP_WIN
InitWindowsGroupID();
#endif
}
#ifdef XP_WIN
void GeckoChildProcessHost::InitWindowsGroupID()
{
@ -262,15 +276,7 @@ void GeckoChildProcessHost::InitWindowsGroupID()
bool
GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs, base::ProcessArchitecture arch)
{
#ifdef MOZ_CRASHREPORTER
if (CrashReporter::GetEnabled()) {
CrashReporter::OOPInit();
}
#endif
#ifdef XP_WIN
InitWindowsGroupID();
#endif
PrepareLaunch();
PRIntervalTime timeoutTicks = (aTimeoutMs > 0) ?
PR_MillisecondsToInterval(aTimeoutMs) : PR_INTERVAL_NO_TIMEOUT;
@ -309,15 +315,7 @@ GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTime
bool
GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts)
{
#ifdef MOZ_CRASHREPORTER
if (CrashReporter::GetEnabled()) {
CrashReporter::OOPInit();
}
#endif
#ifdef XP_WIN
InitWindowsGroupID();
#endif
PrepareLaunch();
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
ioLoop->PostTask(FROM_HERE,
@ -335,6 +333,26 @@ GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts)
return true;
}
bool
GeckoChildProcessHost::LaunchAndWaitForProcessHandle(StringVector aExtraOpts)
{
PrepareLaunch();
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
ioLoop->PostTask(FROM_HERE,
NewRunnableMethod(this,
&GeckoChildProcessHost::PerformAsyncLaunch,
aExtraOpts, base::GetCurrentProcessArchitecture()));
MonitorAutoLock lock(mMonitor);
while (mProcessState < PROCESS_CREATED) {
lock.Wait();
}
MOZ_ASSERT(mProcessState == PROCESS_ERROR || mChildProcessHandle);
return mProcessState < PROCESS_ERROR;
}
void
GeckoChildProcessHost::InitializeChannel()
{

View File

@ -23,6 +23,7 @@ class GeckoChildProcessHost : public ChildProcessHost
{
protected:
typedef mozilla::Monitor Monitor;
typedef std::vector<std::string> StringVector;
public:
typedef base::ProcessHandle ProcessHandle;
@ -36,11 +37,33 @@ public:
static uint32 GetSupportedArchitecturesForProcessType(GeckoProcessType type);
bool SyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>(),
// Block until the IPC channel for our subprocess is initialized,
// but no longer. The child process may or may not have been
// created when this method returns.
bool AsyncLaunch(StringVector aExtraOpts=StringVector());
// Block until the IPC channel for our subprocess is initialized and
// the OS process is created. The subprocess may or may not have
// connected back to us when this method returns.
//
// NB: on POSIX, this method is relatively cheap, and doesn't
// require disk IO. On win32 however, it requires at least the
// analogue of stat(). This difference induces a semantic
// difference in this method: on POSIX, when we return, we know the
// subprocess has been created, but we don't know whether its
// executable image can be loaded. On win32, we do know that when
// we return. But we don't know if dynamic linking succeeded on
// either platform.
bool LaunchAndWaitForProcessHandle(StringVector aExtraOpts=StringVector());
// Block until the child process has been created and it connects to
// the IPC channel, meaning it's fully initialized. (Or until an
// error occurs.)
bool SyncLaunch(StringVector aExtraOpts=StringVector(),
int32 timeoutMs=0,
base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
bool AsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
bool PerformAsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>(),
bool PerformAsyncLaunch(StringVector aExtraOpts=StringVector(),
base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
virtual void OnChannelConnected(int32 peer_pid);
@ -96,6 +119,8 @@ protected:
static PRInt32 mChildCounter;
void PrepareLaunch();
#ifdef XP_WIN
void InitWindowsGroupID();
nsString mGroupId;