1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_CHILD_PROCESS_TASK_PORT_PROVIDER_MAC_H_ 6 #define CONTENT_BROWSER_CHILD_PROCESS_TASK_PORT_PROVIDER_MAC_H_ 7 8 #include <map> 9 10 #include "base/mac/dispatch_source_mach.h" 11 #include "base/mac/scoped_mach_port.h" 12 #include "base/macros.h" 13 #include "base/no_destructor.h" 14 #include "base/process/port_provider_mac.h" 15 #include "base/process/process_handle.h" 16 #include "base/synchronization/lock.h" 17 #include "content/common/child_process.mojom-forward.h" 18 #include "content/common/content_export.h" 19 #include "mojo/public/cpp/platform/platform_handle.h" 20 21 namespace content { 22 23 // The ChildProcessTaskPortProvider keeps an association between a PID and the 24 // process's task port. This association is needed for the browser to manipulate 25 // certain aspects of its child processes. 26 class CONTENT_EXPORT ChildProcessTaskPortProvider : public base::PortProvider { 27 public: 28 // Returns the singleton instance. 29 static ChildProcessTaskPortProvider* GetInstance(); 30 31 // Called by BrowserChildProcessHostImpl and RenderProcessHostImpl when 32 // a new child has been created. This will invoke the GetTaskPort() method 33 // on |child_control| and will store the returned port as being associated to 34 // |pid|. 35 // 36 // When the kernel sends a notification that the port has become a dead name, 37 // indicating that the child process has died, the association will be 38 // removed. 39 void OnChildProcessLaunched(base::ProcessHandle pid, 40 mojom::ChildProcess* child_process); 41 42 // base::PortProvider: 43 mach_port_t TaskForPid(base::ProcessHandle process) const override; 44 45 private: 46 friend class ChildProcessTaskPortProviderTest; 47 friend base::NoDestructor<ChildProcessTaskPortProvider>; 48 49 ChildProcessTaskPortProvider(); 50 ~ChildProcessTaskPortProvider() override; 51 52 // Callback for mojom::ChildProcess::GetTaskPort reply. 53 void OnTaskPortReceived(base::ProcessHandle pid, 54 mojo::PlatformHandle task_port); 55 56 // Event handler for |notification_source_|, invoked for 57 // MACH_NOTIFY_DEAD_NAME. 58 void OnTaskPortDied(); 59 60 // Lock that protects the map below. 61 mutable base::Lock lock_; 62 63 // Maps a PID to the corresponding task port. 64 using PidToTaskPortMap = 65 std::map<base::ProcessHandle, base::mac::ScopedMachSendRight>; 66 PidToTaskPortMap pid_to_task_port_; 67 68 // A Mach port that is used to register for dead name notifications from 69 // the kernel. All the ports in |pid_to_task_port_| have a notification set 70 // up to send to this port. 71 base::mac::ScopedMachReceiveRight notification_port_; 72 73 // Dispatch source for |notification_port_|. 74 std::unique_ptr<base::DispatchSourceMach> notification_source_; 75 76 DISALLOW_COPY_AND_ASSIGN(ChildProcessTaskPortProvider); 77 }; 78 79 } // namespace content 80 81 #endif // CONTENT_BROWSER_CHILD_PROCESS_TASK_PORT_PROVIDER_MAC_H_ 82