2009-06-29 22:38:29 +04:00
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is Mozilla IPC.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Ben Turner <bent.mozilla@gmail.com>.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
#include "GeckoChildProcessHost.h"
|
|
|
|
|
|
|
|
#include "base/command_line.h"
|
|
|
|
#include "base/path_service.h"
|
2009-07-10 23:03:09 +04:00
|
|
|
#include "base/string_util.h"
|
2009-06-29 22:38:29 +04:00
|
|
|
#include "chrome/common/chrome_switches.h"
|
|
|
|
|
2009-07-20 22:14:41 +04:00
|
|
|
#include "mozilla/ipc/GeckoThread.h"
|
|
|
|
|
|
|
|
using mozilla::MonitorAutoEnter;
|
2009-06-29 22:38:29 +04:00
|
|
|
using mozilla::ipc::GeckoChildProcessHost;
|
|
|
|
|
2009-07-20 22:14:41 +04:00
|
|
|
template<>
|
|
|
|
struct RunnableMethodTraits<GeckoChildProcessHost>
|
|
|
|
{
|
|
|
|
static void RetainCallee(GeckoChildProcessHost* obj) { }
|
|
|
|
static void ReleaseCallee(GeckoChildProcessHost* obj) { }
|
|
|
|
};
|
|
|
|
|
2009-08-19 21:09:51 +04:00
|
|
|
GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType)
|
2009-07-10 23:03:09 +04:00
|
|
|
: ChildProcessHost(RENDER_PROCESS), // FIXME/cjones: we should own this enum
|
2009-07-20 22:14:41 +04:00
|
|
|
mProcessType(aProcessType),
|
|
|
|
mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
|
|
|
|
mLaunched(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GeckoChildProcessHost::SyncLaunch(std::vector<std::wstring> aExtraOpts)
|
2009-06-29 22:38:29 +04:00
|
|
|
{
|
2009-07-20 22:14:41 +04:00
|
|
|
MessageLoop* loop = MessageLoop::current();
|
|
|
|
MessageLoop* ioLoop =
|
|
|
|
BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO);
|
|
|
|
NS_ASSERTION(loop != ioLoop, "sync launch from the IO thread NYI");
|
|
|
|
|
|
|
|
ioLoop->PostTask(FROM_HERE,
|
|
|
|
NewRunnableMethod(this,
|
|
|
|
&GeckoChildProcessHost::AsyncLaunch,
|
|
|
|
aExtraOpts));
|
|
|
|
|
|
|
|
// NB: this uses a different mechanism than the chromium parent
|
|
|
|
// class.
|
|
|
|
MonitorAutoEnter mon(mMonitor);
|
|
|
|
while (!mLaunched) {
|
|
|
|
mon.Wait();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2009-06-29 22:38:29 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2009-07-20 22:14:41 +04:00
|
|
|
GeckoChildProcessHost::AsyncLaunch(std::vector<std::wstring> aExtraOpts)
|
2009-06-29 22:38:29 +04:00
|
|
|
{
|
2009-07-20 22:14:41 +04:00
|
|
|
// FIXME/cjones: make this work from non-IO threads, too
|
|
|
|
|
2009-06-29 22:38:29 +04:00
|
|
|
if (!CreateChannel()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
FilePath exePath =
|
|
|
|
FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
|
|
|
|
exePath = exePath.DirName();
|
|
|
|
|
2009-07-10 23:03:09 +04:00
|
|
|
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
|
2009-06-29 22:38:29 +04:00
|
|
|
|
2009-07-10 23:03:09 +04:00
|
|
|
// remap the IPC socket fd to a well-known int, as the OS does for
|
|
|
|
// STDOUT_FILENO, for example
|
|
|
|
#if defined(OS_POSIX)
|
2009-06-29 22:38:29 +04:00
|
|
|
int srcChannelFd, dstChannelFd;
|
|
|
|
channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd);
|
|
|
|
mFileMap.push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
CommandLine cmdLine(exePath.ToWStringHack());
|
|
|
|
cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id());
|
|
|
|
|
2009-07-10 23:03:09 +04:00
|
|
|
for (std::vector<std::wstring>::iterator it = aExtraOpts.begin();
|
|
|
|
it != aExtraOpts.end();
|
|
|
|
++it) {
|
|
|
|
cmdLine.AppendLooseValue((*it).c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
cmdLine.AppendLooseValue(UTF8ToWide(XRE_ChildProcessTypeToString(mProcessType)));
|
|
|
|
|
2009-06-29 22:38:29 +04:00
|
|
|
base::ProcessHandle process;
|
|
|
|
#if defined(OS_WIN)
|
|
|
|
base::LaunchApp(cmdLine, false, false, &process);
|
|
|
|
#elif defined(OS_POSIX)
|
|
|
|
base::LaunchApp(cmdLine.argv(), mFileMap, false, &process);
|
|
|
|
#else
|
|
|
|
#error Bad!
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!process) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
SetHandle(process);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-07-14 09:12:50 +04:00
|
|
|
void
|
|
|
|
GeckoChildProcessHost::OnChannelConnected(int32 peer_pid)
|
|
|
|
{
|
2009-07-20 22:14:41 +04:00
|
|
|
MonitorAutoEnter mon(mMonitor);
|
|
|
|
mLaunched = true;
|
|
|
|
mon.Notify();
|
2009-07-14 09:12:50 +04:00
|
|
|
}
|
2009-07-20 22:14:41 +04:00
|
|
|
|
|
|
|
// XXX/cjones: these next two methods should basically never be called.
|
|
|
|
// after the process is launched, its channel will be used to create
|
|
|
|
// one of our channels, AsyncChannel et al.
|
2009-06-29 22:38:29 +04:00
|
|
|
void
|
|
|
|
GeckoChildProcessHost::OnMessageReceived(const IPC::Message& aMsg)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void
|
|
|
|
GeckoChildProcessHost::OnChannelError()
|
|
|
|
{
|
|
|
|
// XXXbent Notify that the child process is gone?
|
|
|
|
}
|