Chromium Code Reviews| Index: chrome/browser/child_process_launcher.cc |
| diff --git a/chrome/browser/child_process_launcher.cc b/chrome/browser/child_process_launcher.cc |
| index 1ab66c63dec021b27bfd78b589bf2de0866caf37..2573c4f8a6087cd8c068a196a7ac92fbeefd3cee 100644 |
| --- a/chrome/browser/child_process_launcher.cc |
| +++ b/chrome/browser/child_process_launcher.cc |
| @@ -27,6 +27,93 @@ |
| #include "base/global_descriptors_posix.h" |
| #endif |
| +#if defined(OS_MACOSX) |
| +#include "ipc/ipc_switches.h" |
| +#include "chrome/browser/mach_broker_mac.h" |
| +#include "chrome/common/mach_ipc_mac.h" |
| +#endif |
| + |
| +#if defined(OS_MACOSX) |
| +class MachTask : public Task { |
| + public: |
| + MachTask(std::string channel_name, mach_port_t* task) |
| + : task_(task) { |
| + // TODO(thakis): Move some place central |
|
Mark Mentovai
2010/01/11 20:22:46
Wanna do this now?
|
| + const std::string kMachChannelPrefix = "com.Google.Chrome"; |
| + std::string channel = kMachChannelPrefix + channel_name; |
|
Mark Mentovai
2010/01/11 20:22:46
Unless channel_name begins with a dot, this will g
|
| + |
| + MachBroker::instance(); // make sure registrations are registered on the right thread. |
|
Mark Mentovai
2010/01/11 20:22:46
80
|
| + |
| + // This creates our named server port -- needs to happen on the current |
| + // thread. |
| +printf("Creating receive port %s\n", channel.c_str()); |
|
Mark Mentovai
2010/01/11 20:22:46
Debugging turdlet?
(I leave my debugging turdlets
|
| + port_.reset(new ReceivePort(channel.c_str())); |
| + } |
| + |
| + virtual void Run() { |
| + // TODO(thakis): Move some place central |
| + const int kMachPortMessageID = 57; |
|
Mark Mentovai
2010/01/11 20:22:46
Magic?
|
| + |
| + const int kMachPortMessageReceiveWaitMs = 1000; |
| + |
| + // TODO(thakis): time histogram between creation and port reception? |
| + MachReceiveMessage message; |
| + kern_return_t result = port_->WaitForMessage( |
| + &message, kMachPortMessageReceiveWaitMs); |
| + if (result == KERN_SUCCESS) { |
| + CHECK(kMachPortMessageID == message.GetMessageID()); |
|
Mark Mentovai
2010/01/11 20:22:46
CHECK_EQ?
|
| + CHECK(1 == message.GetDescriptorCount()); |
|
Mark Mentovai
2010/01/11 20:22:46
CHECK_EQ?
|
| + *task_ = message.GetTranslatedPort(0); |
| + printf("yay\n"); |
|
Mark Mentovai
2010/01/11 20:22:46
Debugging turdlet?
|
| + } else { |
| + // TODO(thakis): Log somewhere? |
| + *task_ = 0; |
| + printf("nay\n"); |
|
Mark Mentovai
2010/01/11 20:22:46
LOG?
|
| + } |
| + } |
| + |
| + private: |
| + scoped_ptr<ReceivePort> port_; |
| + mach_port_t* task_; |
| +}; |
| + |
| +class MachTask2 : public Task { |
|
Mark Mentovai
2010/01/11 20:22:46
Class-level comments would be nice for this and fo
|
| + public: |
| + MachTask2(const mach_port_t& task, base::ProcessHandle pid) // must be refs, might be 0 at call time and only be set later on the other thread |
|
Mark Mentovai
2010/01/11 20:22:46
80
|
| + : task_(task), pid_(pid) {} |
| + |
| + virtual void Run() { |
| + if (task_) |
|
Mark Mentovai
2010/01/11 20:22:46
You need {} here because this thing spills over a
|
| + MachBroker::instance()->RegisterPid( |
| + pid_, |
| + MachBroker::MachInfo().SetTask(task_)); |
| + } |
| + private: |
| + const mach_port_t& task_; |
| + base::ProcessHandle pid_; |
| +}; |
| + |
| +class MachThread : public base::Thread { |
| + public: |
| + MachThread() : base::Thread("MachThread"), task_(0) {} |
|
Mark Mentovai
2010/01/11 20:22:46
task_(MACH_PORT_NULL) ?
|
| + |
| + void DoIt(const std::string& channel_name) { |
| + DCHECK(message_loop()); |
| + message_loop()->PostTask(FROM_HERE, |
| + new MachTask(channel_name, &task_)); |
| + } |
| + |
| + void DoIt2(base::ProcessHandle pid) { |
|
Mark Mentovai
2010/01/11 20:22:46
Oh, so is this just to avoid the ban on overloadin
|
| + DCHECK(message_loop()); |
| + message_loop()->PostTask(FROM_HERE, |
| + new MachTask2(task_, pid)); |
| + } |
| + |
| + private: |
| + mach_port_t task_; |
| +}; |
| +#endif |
| + |
| // Having the functionality of ChildProcessLauncher be in an internal |
| // ref counted object allows us to automatically terminate the process when the |
| // parent class destructs, while still holding on to state that we need. |
| @@ -160,9 +247,37 @@ class ChildProcessLauncher::Context |
| } |
| #endif // defined(OS_LINUX) |
| +#if defined(OS_MACOSX) |
| + // TODO(thakis): Possibly somewhere else? |
| + // (then again, the fds duping stuff is here too, so maybe it's ok) |
| + bool is_renderer = cmd_line->GetSwitchValueASCII(switches::kProcessType) |
| + == switches::kRendererProcess; |
| + bool is_extension = cmd_line->GetSwitchValueASCII(switches::kProcessType) == |
|
Mark Mentovai
2010/01/11 20:22:46
Fix indent?
This whole section (253-256) should b
|
| + switches::kExtensionProcess; |
| + |
| +for (size_t ii = 0; ii < cmd_line->argv().size(); ++ii) |
|
Mark Mentovai
2010/01/11 20:22:46
Debugging turdlets?
|
| + fprintf(stderr, "%s ", cmd_line->argv()[ii].c_str()); |
| +fprintf(stderr, "\n"); |
| +fprintf(stderr, "child type: %s\n", cmd_line->GetSwitchValueASCII(switches::kProcessType).c_str()); |
| + MachThread mach_thread; |
|
Mark Mentovai
2010/01/11 20:22:46
Fix the indent in here too?
|
| + if (true || is_renderer || is_extension) { |
|
Mark Mentovai
2010/01/11 20:22:46
Remove "true" - debugging turdlet?
|
| + CHECK(mach_thread.Start()); |
| + mach_thread.DoIt( |
| + cmd_line->GetSwitchValueASCII(switches::kProcessChannelID)); |
| + } |
| +#endif |
| + |
| + |
| // Actually launch the app. |
| if (!base::LaunchApp(cmd_line->argv(), env, fds_to_map, false, &handle)) |
| handle = base::kNullProcessHandle; |
| + |
| +#if defined(OS_MACOSX) |
| + if (true || is_renderer || is_extension) { |
|
Mark Mentovai
2010/01/11 20:22:46
true
|
| + // TODO(thakis): Check |handle| first. |
| + mach_thread.DoIt2(handle); |
| + } |
| +#endif |
| } |
| #endif |
| @@ -277,7 +392,7 @@ bool ChildProcessLauncher::IsStarting() { |
| } |
| base::ProcessHandle ChildProcessLauncher::GetHandle() { |
| - DCHECK(!context_->starting_); |
| +// DCHECK(!context_->starting_); |
|
Mark Mentovai
2010/01/11 20:22:46
?
|
| return context_->process_.handle(); |
| } |