| // Copyright (c) 2012 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_COMMON_SERVICE_PROCESS_UTIL_H_ |
| #define CHROME_COMMON_SERVICE_PROCESS_UTIL_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/callback_forward.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/read_only_shared_memory_region.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/writable_shared_memory_region.h" |
| #include "base/process/process.h" |
| #include "base/single_thread_task_runner.h" |
| #include "build/build_config.h" |
| #include "mojo/public/cpp/platform/named_platform_channel.h" |
| #include "mojo/public/cpp/platform/platform_channel_server_endpoint.h" |
| |
| class MultiProcessLock; |
| |
| namespace base { |
| class CommandLine; |
| } |
| |
| // Return the IPC channel to connect to the service process. |
| mojo::NamedPlatformChannel::ServerName GetServiceProcessServerName(); |
| |
| // Return a name that is scoped to this instance of the service process. We |
| // use the user-data-dir as a scoping prefix. |
| std::string GetServiceProcessScopedName(const std::string& append_str); |
| |
| #if !defined(OS_MAC) |
| // Return a name that is scoped to this instance of the service process. We |
| // use the user-data-dir and the version as a scoping prefix. |
| std::string GetServiceProcessScopedVersionedName(const std::string& append_str); |
| #endif // !OS_MAC |
| |
| #if defined(OS_POSIX) |
| // Attempts to take a session-wide lock named name. Returns a non-null lock if |
| // successful. |
| std::unique_ptr<MultiProcessLock> TakeNamedLock(const std::string& name); |
| #endif |
| |
| // The following method is used in a process that acts as a client to the |
| // service process (typically the browser process). It method checks that if the |
| // service process is ready to receive IPC commands. |
| bool CheckServiceProcessReady(); |
| |
| // -------------------------------------------------------------------------- |
| |
| // Forces a service process matching the specified version to shut down. |
| bool ForceServiceProcessShutdown(const std::string& version, |
| base::ProcessId process_id); |
| |
| // Creates command-line to run the service process. |
| std::unique_ptr<base::CommandLine> CreateServiceProcessCommandLine(); |
| |
| // This is a class that is used by the service process to signal events and |
| // share data with external clients. This class lives in this file because the |
| // internal data structures and mechanisms used by the utility methods above |
| // and this class are shared. |
| class ServiceProcessState { |
| public: |
| ServiceProcessState(); |
| ~ServiceProcessState(); |
| |
| // Tries to become the sole service process for the current user data dir. |
| // Returns false if another service process is already running. |
| bool Initialize(); |
| |
| // Signal that the service process is ready. |
| // This method is called when the service process is running and initialized. |
| // |terminate_task| is invoked when we get a terminate request from another |
| // process (in the same thread that called SignalReady). It can be NULL. |
| // |task_runner| must be of type IO and is the loop that POSIX uses |
| // to monitor the service process. |
| bool SignalReady(scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| base::OnceClosure terminate_task); |
| |
| // Signal that the service process is stopped. |
| void SignalStopped(); |
| |
| // Register the service process to run on startup. |
| bool AddToAutoRun(); |
| |
| // Unregister the service process to run on startup. |
| bool RemoveFromAutoRun(); |
| |
| // Return the channel handle used for communicating with the service. |
| #if defined(OS_MAC) |
| mojo::PlatformChannelServerEndpoint GetServiceProcessServerEndpoint(); |
| #else |
| mojo::NamedPlatformChannel::ServerName GetServiceProcessServerName(); |
| #endif |
| |
| private: |
| #if !defined(OS_MAC) |
| enum ServiceProcessRunningState { |
| SERVICE_NOT_RUNNING, |
| SERVICE_OLDER_VERSION_RUNNING, |
| SERVICE_SAME_VERSION_RUNNING, |
| SERVICE_NEWER_VERSION_RUNNING, |
| }; |
| |
| // Create the shared memory data for the service process. |
| bool CreateSharedData(); |
| |
| // If an older version of the service process running, it should be shutdown. |
| // Returns false if this process needs to exit. |
| bool HandleOtherVersion(); |
| |
| // Acquires a singleton lock for the service process. A return value of false |
| // means that a service process instance is already running. |
| bool TakeSingletonLock(); |
| |
| // Return a name used to name a shared memory file that will be used to locate |
| // the currently running service process. |
| static std::string GetServiceProcessSharedMemName(); |
| |
| // Create a writable service process data shared memory region of the |
| // specified size. Returns an invalid region on error. If the backing file for |
| // the shared memory region already exists but is smaller than |size|, this |
| // function may return a valid region which will fail to be mapped. |
| static base::WritableSharedMemoryRegion CreateServiceProcessDataRegion( |
| size_t size); |
| |
| // Open an existing service process data shared memory region of the specified |
| // size. Returns an invalid region on error. Note that if the size of the |
| // existing region is smaller than |size|, this function may return a valid |
| // region which will fail to be mapped. Also note that since the underlying |
| // file is writable, the region cannot be read-only. |
| static base::ReadOnlySharedMemoryMapping OpenServiceProcessDataMapping( |
| size_t size); |
| |
| // Deletes a service process data shared memory backing file. Returns false if |
| // the file was not able to be deleted. |
| static bool DeleteServiceProcessDataRegion(); |
| |
| static ServiceProcessRunningState GetServiceProcessRunningState( |
| std::string* service_version_out, |
| base::ProcessId* pid_out); |
| #endif // !OS_MAC |
| |
| // Returns the process id and version of the currently running service |
| // process. Note: DO NOT use this check whether the service process is ready |
| // because a true return value only means that some process shared data was |
| // available, and not that the process is ready to receive IPC commands, or |
| // even running. |
| static bool GetServiceProcessData(std::string* version, base::ProcessId* pid); |
| |
| // Creates the platform specific state. |
| void CreateState(); |
| |
| // Tear down the platform specific state. |
| void TearDownState(); |
| |
| // An opaque object that maintains state. The actual definition of this is |
| // platform dependent. |
| struct StateData; |
| StateData* state_; |
| |
| #if !defined(OS_MAC) |
| // The shared memory mapping backing the shared state on non-macos |
| // platforms. This is actually referring to named shared memory, and on some |
| // platforms (eg, Windows) determines the lifetime of when consumers are able |
| // to open the named shared region. This means this region must stay alive |
| // for the named region to be visible. |
| base::WritableSharedMemoryRegion service_process_data_region_; |
| #endif |
| |
| std::unique_ptr<base::CommandLine> autorun_command_line_; |
| |
| #if defined(OS_MAC) |
| friend bool CheckServiceProcessReady(); |
| #endif |
| |
| FRIEND_TEST_ALL_PREFIXES(ServiceProcessStateTest, SharedMem); |
| FRIEND_TEST_ALL_PREFIXES(ServiceProcessStateTest, ForceShutdown); |
| |
| friend class ServiceProcessControlBrowserTest; |
| FRIEND_TEST_ALL_PREFIXES(ServiceProcessControlBrowserTest, ForceShutdown); |
| FRIEND_TEST_ALL_PREFIXES(ServiceProcessControlBrowserTest, CheckPid); |
| }; |
| |
| #endif // CHROME_COMMON_SERVICE_PROCESS_UTIL_H_ |