summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-09 07:54:32 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-09 07:54:32 +0000
commit2191d2082e2bf1f937ec4592b4f8c185f04f3fd6 (patch)
tree72193cc3ae1951e91924353de58a1f2ed7c8af23 /chrome/browser
parent04df4f1ea242136c0829b8d922c3aefdbb4ebd85 (diff)
downloadchromium_src-2191d2082e2bf1f937ec4592b4f8c185f04f3fd6.zip
chromium_src-2191d2082e2bf1f937ec4592b4f8c185f04f3fd6.tar.gz
chromium_src-2191d2082e2bf1f937ec4592b4f8c185f04f3fd6.tar.bz2
A place to store the pid->mach_port_t mapping.
Not yet for review. Landing to measure perf impact, will revert immediately. BUG=13156 TEST=unittests Review URL: http://codereview.chromium.org/460126 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34146 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/child_process_launcher.cc109
-rw-r--r--chrome/browser/mach_broker_mac.cc47
-rw-r--r--chrome/browser/mach_broker_mac.h81
-rw-r--r--chrome/browser/mach_broker_mac_unittest.cc29
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc9
-rw-r--r--chrome/browser/task_manager.cc6
-rw-r--r--chrome/browser/task_manager.h9
7 files changed, 287 insertions, 3 deletions
diff --git a/chrome/browser/child_process_launcher.cc b/chrome/browser/child_process_launcher.cc
index 956f836..843188f 100644
--- a/chrome/browser/child_process_launcher.cc
+++ b/chrome/browser/child_process_launcher.cc
@@ -27,6 +27,99 @@
#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, mach_port_t* host)
+ : task_(task), host_(host) {
+ // TODO(thakis): Move some place central
+ const std::string kMachChannelPrefix = "com.Google.Chrome";
+ std::string channel = kMachChannelPrefix + channel_name;
+
+ // This creates our named server port -- needs to happen on the current
+ // thread.
+printf("Creating receive port %s\n", channel.c_str());
+ port_.reset(new ReceivePort(channel.c_str()));
+ }
+
+ virtual void Run() {
+ // TODO(thakis): Move some place central
+ const int kMachPortMessageID = 57;
+
+ const int kMachPortMessageReceiveWaitMs = 1000;
+
+
+
+ //ReceivePort receivePort(channel_name.c_str());
+
+ // 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());
+ CHECK(2 == message.GetDescriptorCount());
+
+ // TODO(thakis): Constants for the indices?
+ *task_ = message.GetTranslatedPort(0);
+ *host_ = message.GetTranslatedPort(1);
+ printf("yay\n");
+ } else {
+ // TODO(thakis): Log somewhere?
+ printf("nay\n");
+ }
+ }
+
+ private:
+ scoped_ptr<ReceivePort> port_;
+ mach_port_t* task_;
+ mach_port_t* host_;
+};
+
+class MachTask2 : public Task {
+ public:
+ MachTask2(mach_port_t task, mach_port_t host, base::ProcessHandle pid)
+ : task_(task), host_(host), pid_(pid) {}
+
+ virtual void Run() {
+ MachBroker::instance()->RegisterPid(
+ pid_,
+ MachBroker::MachInfo().SetTask(task_).SetHost(host_));
+ }
+ private:
+ mach_port_t task_;
+ mach_port_t host_;
+ base::ProcessHandle pid_;
+};
+
+class MachThread : public base::Thread {
+ public:
+ MachThread() : base::Thread("MachThread"), task_(0), host_(0) {}
+
+ void DoIt(const std::string& channel_name) {
+ DCHECK(message_loop());
+ message_loop()->PostTask(FROM_HERE,
+ new MachTask(channel_name, &task_, &host_));
+ }
+
+ void DoIt2(base::ProcessHandle pid) {
+ DCHECK(message_loop());
+ message_loop()->PostTask(FROM_HERE,
+ new MachTask2(task_, host_, pid));
+ }
+
+ private:
+ mach_port_t task_;
+ mach_port_t host_;
+};
+#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 +253,25 @@ 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)
+
+ MachThread mach_thread;
+ 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)
+ // TODO(thakis): Check |handle| first.
+ mach_thread.DoIt2(handle);
+#endif
}
#endif
diff --git a/chrome/browser/mach_broker_mac.cc b/chrome/browser/mach_broker_mac.cc
new file mode 100644
index 0000000..6d9779e
--- /dev/null
+++ b/chrome/browser/mach_broker_mac.cc
@@ -0,0 +1,47 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/mach_broker_mac.h"
+
+#include "base/logging.h"
+
+// Constructor.
+MachBroker::MachBroker() {}
+
+// Returns the global MachBroker.
+MachBroker* MachBroker::instance() {
+ return Singleton<MachBroker>::get();
+}
+
+// Returns the mach task belonging to |pid|.
+mach_port_t MachBroker::MachTaskForPid(base::ProcessHandle pid) const {
+ AutoLock lock(lock_);
+ MachBroker::MachMap::const_iterator it = mach_map_.find(pid);
+ if (it == mach_map_.end())
+ return 0;
+ return it->second.mach_task_;
+}
+
+// Returns the mach host belonging to |pid|.
+mach_port_t MachBroker::MachHostForPid(base::ProcessHandle pid) const {
+ AutoLock lock(lock_);
+ MachMap::const_iterator it = mach_map_.find(pid);
+ if (it == mach_map_.end())
+ return 0;
+ return it->second.mach_host_;
+}
+
+// Adds mach info for a given pid.
+void MachBroker::RegisterPid(
+ base::ProcessHandle pid, const MachInfo& mach_info) {
+ AutoLock lock(lock_);
+ DCHECK(mach_map_.count(pid) == 0);
+ mach_map_[pid] = mach_info;
+}
+
+// Removes all mappings belonging to |pid| from the broker.
+void MachBroker::Invalidate(base::ProcessHandle pid) {
+ AutoLock lock(lock_);
+ mach_map_.erase(pid);
+}
diff --git a/chrome/browser/mach_broker_mac.h b/chrome/browser/mach_broker_mac.h
new file mode 100644
index 0000000..5672db5
--- /dev/null
+++ b/chrome/browser/mach_broker_mac.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_MACH_BROKER_H_
+#define CHROME_BROWSER_MACH_BROKER_H_
+
+#include <map>
+
+#include <mach/mach.h>
+
+#include "base/lock.h"
+#include "base/process.h"
+#include "base/singleton.h"
+
+// On OS X, the mach_port_t of a process is required to collect metrics about
+// the process. Running |task_for_pid()| is only allowed for priviledged code.
+// However, a process has port rights to all its subprocesses, so let the
+// browser's child processes send their mach_port_t to the browser over IPC.
+// This way, the brower can at least collect metrics of its child processes,
+// which is what it's most interested in anyway.
+//
+// mach_port_ts can only be sent over mach ipc, not over the socketpair that
+// the regular ipc system uses. Hence, the child processes open a mach
+// connection shortly after launching and ipc their mach data to the browser
+// process. This data is kept in a global |MachBroker| object.
+//
+// Due to this data arriving over a separate channel, it is not available
+// immediately after a child process has been started.
+class MachBroker {
+ public:
+ // Returns the global MachBroker.
+ static MachBroker* instance();
+
+ // Returns the mach task belonging to |pid|, or 0 if no mach task is
+ // registered for |pid|.
+ mach_port_t MachTaskForPid(base::ProcessHandle pid) const;
+
+ // Returns the mach host belonging to |pid|, or 0 if no mach task is
+ // registered for |pid|.
+ mach_port_t MachHostForPid(base::ProcessHandle pid) const;
+
+ struct MachInfo {
+ MachInfo() : mach_task_(0), mach_host_(0) {}
+
+ MachInfo& SetTask(mach_port_t task) {
+ mach_task_ = task;
+ return *this;
+ }
+
+ MachInfo& SetHost(mach_port_t host) {
+ mach_host_ = host;
+ return *this;
+ }
+
+ mach_port_t mach_task_;
+ mach_port_t mach_host_;
+ };
+
+ // Adds mach info for a given pid.
+ void RegisterPid(base::ProcessHandle pid, const MachInfo& mach_info);
+
+ // Removes all mappings belonging to |pid| from the broker.
+ void Invalidate(base::ProcessHandle pid);
+
+ private:
+ // Private constructor.
+ MachBroker();
+ friend struct DefaultSingletonTraits<MachBroker>;
+ friend class MachBrokerTest;
+
+ // Stores
+ typedef std::map<base::ProcessHandle, MachInfo> MachMap;
+ MachMap mach_map_;
+
+ // Mutex that guards |mach_map_|.
+ mutable Lock lock_;
+};
+
+#endif // CHROME_BROWSER_MACH_BROKER_H_
+
diff --git a/chrome/browser/mach_broker_mac_unittest.cc b/chrome/browser/mach_broker_mac_unittest.cc
new file mode 100644
index 0000000..745d0d7
--- /dev/null
+++ b/chrome/browser/mach_broker_mac_unittest.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/mach_broker_mac.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+class MachBrokerTest : public testing::Test {
+ public:
+ MachBroker broker_;
+};
+
+TEST_F(MachBrokerTest, Setter) {
+ broker_.RegisterPid(1u, MachBroker::MachInfo().SetTask(2u).SetHost(3u));
+
+ EXPECT_EQ(2u, broker_.MachTaskForPid(1));
+ EXPECT_EQ(3u, broker_.MachHostForPid(1));
+
+ EXPECT_EQ(0u, broker_.MachTaskForPid(2));
+ EXPECT_EQ(0u, broker_.MachHostForPid(3));
+}
+
+TEST_F(MachBrokerTest, Invalidate) {
+ broker_.RegisterPid(1u, MachBroker::MachInfo().SetTask(2).SetHost(3));
+ broker_.Invalidate(1u);
+ EXPECT_EQ(0u, broker_.MachTaskForPid(1));
+ EXPECT_EQ(0u, broker_.MachHostForPid(1));
+}
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index c7325ad..8423516 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -62,6 +62,10 @@
#include "app/win_util.h"
#endif
+#if defined(OS_MACOSX)
+#include "chrome/browser/mach_broker_mac.h"
+#endif
+
using WebKit::WebCache;
#include "third_party/skia/include/core/SkBitmap.h"
@@ -837,6 +841,11 @@ void BrowserRenderProcessHost::OnChannelError() {
ClearTransportDIBCache();
+#if defined(OS_MACOSX)
+ if (child_process_.get())
+ MachBroker::instance()->Invalidate(child_process_->GetHandle());
+#endif
+
// this object is not deleted at this point and may be reused later.
// TODO(darin): clean this up
}
diff --git a/chrome/browser/task_manager.cc b/chrome/browser/task_manager.cc
index 43952a5..cd059be 100644
--- a/chrome/browser/task_manager.cc
+++ b/chrome/browser/task_manager.cc
@@ -770,12 +770,12 @@ void TaskManagerModel::OnJobRemoved(URLRequestJob* job) {
}
void TaskManagerModel::OnJobDone(URLRequestJob* job,
- const URLRequestStatus& status) {
+ const URLRequestStatus& status) {
}
void TaskManagerModel::OnJobRedirect(URLRequestJob* job,
- const GURL& location,
- int status_code) {
+ const GURL& location,
+ int status_code) {
}
void TaskManagerModel::OnBytesRead(URLRequestJob* job, int byte_count) {
diff --git a/chrome/browser/task_manager.h b/chrome/browser/task_manager.h
index f49e1e5..3df4653 100644
--- a/chrome/browser/task_manager.h
+++ b/chrome/browser/task_manager.h
@@ -46,6 +46,15 @@ class TaskManager {
virtual std::wstring GetTitle() const = 0;
virtual SkBitmap GetIcon() const = 0;
virtual base::ProcessHandle GetProcess() const = 0;
+#if defined(OS_MACOSX)
+ // TODO(thakis): All the providers need to get these somewhere (child
+ // processes need to IPC them to us via mach IPC at some point).
+ // TODO(thakis): TMM needs to hand this on to ProcessMetrics.
+ // TODO(thakis): ProcessMetrics then needs to call mach data collection apis
+ // if it has the mach ports it needs.
+ virtual mach_port_t GetMachHostPort() const { return 0; };
+ virtual mach_port_t GetMachTaskPort() const { return 0; };
+#endif
virtual bool ReportsCacheStats() const { return false; }
virtual WebKit::WebCache::ResourceTypeStats GetWebCoreCacheStats() const {