1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
// 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_
|