diff options
author | rohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-17 12:28:32 +0000 |
---|---|---|
committer | rohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-17 12:28:32 +0000 |
commit | b88a7498e267ac265b141a2c7693cc37a55c4e9b (patch) | |
tree | 9a27b031d474def81658bdadad42ed05778af6d5 /chrome/browser/mach_broker_mac.h | |
parent | 35e55bffc4738b3dbd68be3f01aa918e56133bc8 (diff) | |
download | chromium_src-b88a7498e267ac265b141a2c7693cc37a55c4e9b.zip chromium_src-b88a7498e267ac265b141a2c7693cc37a55c4e9b.tar.gz chromium_src-b88a7498e267ac265b141a2c7693cc37a55c4e9b.tar.bz2 |
[Mac] Replace the existing browser-child mach ipc with a long-lived listener on a well-known port.
Before this CL:
Before fork()ing a child, the browser process creates a mach receive port with a random name. After the fork() but before exec(), the child uses mach ipc to transmit send rights to its task port. The child has access to the random name because it inherits it from the browser process. Unfortunately, some of the library functions involved in sending a mach message are not safe to call after fork().
After this CL:
Before forking the first child, the browser spins off a new thread that listens on a well-known port for mach ipc from any process. This well-known port is "com.google.Chrome.<browserpid>". When a child process starts up, it sends a mach message to its parent browser's well-known port. On the browser side, we listen for said message, extract the pid of the sending process, and ignore any messages from processes we did not personally fork(). This check is necessary because any arbitrary process on the system could send mach ipc to that port.
BUG=35374
TEST=Browser should still start up. The task manager should still show correct cpu/memory data. There should be no perf regressions.
TEST=Mac ui_tests and browser_tests should be less flaky.
Review URL: http://codereview.chromium.org/3443002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59782 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/mach_broker_mac.h')
-rw-r--r-- | chrome/browser/mach_broker_mac.h | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/chrome/browser/mach_broker_mac.h b/chrome/browser/mach_broker_mac.h index 58ef3e1..7b0257f 100644 --- a/chrome/browser/mach_broker_mac.h +++ b/chrome/browser/mach_broker_mac.h @@ -7,6 +7,7 @@ #pragma once #include <map> +#include <string> #include <mach/mach.h> @@ -37,6 +38,10 @@ class MachBroker : public base::ProcessMetrics::PortProvider, // Returns the global MachBroker. static MachBroker* instance(); + // Performs any necessary setup that cannot happen in the constructor. + // Clients MUST call this method before fork()ing any children. + void PrepareForFork(); + struct MachInfo { MachInfo() : mach_task_(MACH_PORT_NULL) {} @@ -48,11 +53,28 @@ class MachBroker : public base::ProcessMetrics::PortProvider, mach_port_t mach_task_; }; - // Adds mach info for a given pid. - void RegisterPid(base::ProcessHandle pid, const MachInfo& mach_info); + // Adds a placeholder to the map for the given pid with MACH_PORT_NULL. + // Callers are expected to later update the port with FinalizePid(). Callers + // MUST acquire the lock given by GetLock() before calling this method (and + // release the lock afterwards). + void AddPlaceholderForPid(base::ProcessHandle pid); + + // Updates the mapping for |pid| to include the given |mach_info|. Does + // nothing if PlaceholderForPid() has not already been called for the given + // |pid|. Callers MUST acquire the lock given by GetLock() before calling + // this method (and release the lock afterwards). + void FinalizePid(base::ProcessHandle pid, const MachInfo& mach_info); // Removes all mappings belonging to |pid| from the broker. - void Invalidate(base::ProcessHandle pid); + void InvalidatePid(base::ProcessHandle pid); + + // The lock that protects this MachBroker object. Clients MUST acquire and + // release this lock around calls to PlaceholderForPid() and FinalizePid(). + Lock& GetLock(); + + // Returns the Mach port name to use when sending or receiving messages. + // Does the Right Thing in the browser and in child processes. + static std::string GetMachPortName(); // Implement |ProcessMetrics::PortProvider|. virtual mach_port_t TaskForPid(base::ProcessHandle process) const; @@ -65,13 +87,13 @@ class MachBroker : public base::ProcessMetrics::PortProvider, // Private constructor. MachBroker(); + // True if the listener thread has been started. + bool listener_thread_started_; + // Used to register for notifications received by NotificationObserver. // Accessed only on the UI thread. NotificationRegistrar registrar_; - friend struct DefaultSingletonTraits<MachBroker>; - friend class MachBrokerTest; - // Stores mach info for every process in the broker. typedef std::map<base::ProcessHandle, MachInfo> MachMap; MachMap mach_map_; @@ -79,7 +101,10 @@ class MachBroker : public base::ProcessMetrics::PortProvider, // Mutex that guards |mach_map_|. mutable Lock lock_; + friend class MachBrokerTest; friend class RegisterNotificationTask; + // Needed in order to make the constructor private. + friend struct DefaultSingletonTraits<MachBroker>; DISALLOW_COPY_AND_ASSIGN(MachBroker); }; |