1 // Copyright (c) 2012 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 CHROME_COMMON_SERVICE_PROCESS_UTIL_H_ 6 #define CHROME_COMMON_SERVICE_PROCESS_UTIL_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/callback_forward.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/read_only_shared_memory_region.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/writable_shared_memory_region.h" 16 #include "base/process/process.h" 17 #include "base/single_thread_task_runner.h" 18 #include "build/build_config.h" 19 #include "mojo/public/cpp/platform/named_platform_channel.h" 20 #include "mojo/public/cpp/platform/platform_channel_server_endpoint.h" 21 22 class MultiProcessLock; 23 24 namespace base { 25 class CommandLine; 26 } 27 28 // Return the IPC channel to connect to the service process. 29 mojo::NamedPlatformChannel::ServerName GetServiceProcessServerName(); 30 31 // Return a name that is scoped to this instance of the service process. We 32 // use the user-data-dir as a scoping prefix. 33 std::string GetServiceProcessScopedName(const std::string& append_str); 34 35 #if !defined(OS_MAC) 36 // Return a name that is scoped to this instance of the service process. We 37 // use the user-data-dir and the version as a scoping prefix. 38 std::string GetServiceProcessScopedVersionedName(const std::string& append_str); 39 #endif // !OS_MAC 40 41 #if defined(OS_POSIX) 42 // Attempts to take a session-wide lock named name. Returns a non-null lock if 43 // successful. 44 std::unique_ptr<MultiProcessLock> TakeNamedLock(const std::string& name); 45 #endif 46 47 // The following method is used in a process that acts as a client to the 48 // service process (typically the browser process). It method checks that if the 49 // service process is ready to receive IPC commands. 50 bool CheckServiceProcessReady(); 51 52 // -------------------------------------------------------------------------- 53 54 // Forces a service process matching the specified version to shut down. 55 bool ForceServiceProcessShutdown(const std::string& version, 56 base::ProcessId process_id); 57 58 // Creates command-line to run the service process. 59 std::unique_ptr<base::CommandLine> CreateServiceProcessCommandLine(); 60 61 // This is a class that is used by the service process to signal events and 62 // share data with external clients. This class lives in this file because the 63 // internal data structures and mechanisms used by the utility methods above 64 // and this class are shared. 65 class ServiceProcessState { 66 public: 67 ServiceProcessState(); 68 ~ServiceProcessState(); 69 70 // Tries to become the sole service process for the current user data dir. 71 // Returns false if another service process is already running. 72 bool Initialize(); 73 74 // Signal that the service process is ready. 75 // This method is called when the service process is running and initialized. 76 // |terminate_task| is invoked when we get a terminate request from another 77 // process (in the same thread that called SignalReady). It can be NULL. 78 // |task_runner| must be of type IO and is the loop that POSIX uses 79 // to monitor the service process. 80 bool SignalReady(scoped_refptr<base::SingleThreadTaskRunner> task_runner, 81 base::OnceClosure terminate_task); 82 83 // Signal that the service process is stopped. 84 void SignalStopped(); 85 86 // Register the service process to run on startup. 87 bool AddToAutoRun(); 88 89 // Unregister the service process to run on startup. 90 bool RemoveFromAutoRun(); 91 92 // Return the channel handle used for communicating with the service. 93 #if defined(OS_MAC) 94 mojo::PlatformChannelServerEndpoint GetServiceProcessServerEndpoint(); 95 #else 96 mojo::NamedPlatformChannel::ServerName GetServiceProcessServerName(); 97 #endif 98 99 private: 100 #if !defined(OS_MAC) 101 enum ServiceProcessRunningState { 102 SERVICE_NOT_RUNNING, 103 SERVICE_OLDER_VERSION_RUNNING, 104 SERVICE_SAME_VERSION_RUNNING, 105 SERVICE_NEWER_VERSION_RUNNING, 106 }; 107 108 // Create the shared memory data for the service process. 109 bool CreateSharedData(); 110 111 // If an older version of the service process running, it should be shutdown. 112 // Returns false if this process needs to exit. 113 bool HandleOtherVersion(); 114 115 // Acquires a singleton lock for the service process. A return value of false 116 // means that a service process instance is already running. 117 bool TakeSingletonLock(); 118 119 // Return a name used to name a shared memory file that will be used to locate 120 // the currently running service process. 121 static std::string GetServiceProcessSharedMemName(); 122 123 // Create a writable service process data shared memory region of the 124 // specified size. Returns an invalid region on error. If the backing file for 125 // the shared memory region already exists but is smaller than |size|, this 126 // function may return a valid region which will fail to be mapped. 127 static base::WritableSharedMemoryRegion CreateServiceProcessDataRegion( 128 size_t size); 129 130 // Open an existing service process data shared memory region of the specified 131 // size. Returns an invalid region on error. Note that if the size of the 132 // existing region is smaller than |size|, this function may return a valid 133 // region which will fail to be mapped. Also note that since the underlying 134 // file is writable, the region cannot be read-only. 135 static base::ReadOnlySharedMemoryMapping OpenServiceProcessDataMapping( 136 size_t size); 137 138 // Deletes a service process data shared memory backing file. Returns false if 139 // the file was not able to be deleted. 140 static bool DeleteServiceProcessDataRegion(); 141 142 static ServiceProcessRunningState GetServiceProcessRunningState( 143 std::string* service_version_out, 144 base::ProcessId* pid_out); 145 #endif // !OS_MAC 146 147 // Returns the process id and version of the currently running service 148 // process. Note: DO NOT use this check whether the service process is ready 149 // because a true return value only means that some process shared data was 150 // available, and not that the process is ready to receive IPC commands, or 151 // even running. 152 static bool GetServiceProcessData(std::string* version, base::ProcessId* pid); 153 154 // Creates the platform specific state. 155 void CreateState(); 156 157 // Tear down the platform specific state. 158 void TearDownState(); 159 160 // An opaque object that maintains state. The actual definition of this is 161 // platform dependent. 162 struct StateData; 163 StateData* state_; 164 165 #if !defined(OS_MAC) 166 // The shared memory mapping backing the shared state on non-macos 167 // platforms. This is actually referring to named shared memory, and on some 168 // platforms (eg, Windows) determines the lifetime of when consumers are able 169 // to open the named shared region. This means this region must stay alive 170 // for the named region to be visible. 171 base::WritableSharedMemoryRegion service_process_data_region_; 172 #endif 173 174 std::unique_ptr<base::CommandLine> autorun_command_line_; 175 176 #if defined(OS_MAC) 177 friend bool CheckServiceProcessReady(); 178 #endif 179 180 FRIEND_TEST_ALL_PREFIXES(ServiceProcessStateTest, SharedMem); 181 FRIEND_TEST_ALL_PREFIXES(ServiceProcessStateTest, ForceShutdown); 182 183 friend class ServiceProcessControlBrowserTest; 184 FRIEND_TEST_ALL_PREFIXES(ServiceProcessControlBrowserTest, ForceShutdown); 185 FRIEND_TEST_ALL_PREFIXES(ServiceProcessControlBrowserTest, CheckPid); 186 }; 187 188 #endif // CHROME_COMMON_SERVICE_PROCESS_UTIL_H_ 189