Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2292)

Unified Diff: mojo/shell/shell.cc

Issue 1810713002: Cascade shutdown of instances (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@55all_users
Patch Set: . Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/shell/shell.h ('k') | mojo/shell/tests/connect/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/shell/shell.cc
diff --git a/mojo/shell/shell.cc b/mojo/shell/shell.cc
index 4cefbc3708e2a31fa68a36c0528d0211780c6459..1fb16b62795e4f3b52ce354f7316887f2ebecd09 100644
--- a/mojo/shell/shell.cc
+++ b/mojo/shell/shell.cc
@@ -129,28 +129,25 @@ class Shell::Instance : public mojom::Connector,
DCHECK_NE(mojom::kInvalidInstanceID, id_);
}
- ~Instance() override {}
-
- void OnShellClientLost() {
- shell_client_.reset();
- OnConnectionLost();
+ ~Instance() override {
+ if (parent_)
+ parent_->RemoveChild(this);
+ // |children_| will be modified during destruction.
+ std::set<Instance*> children = children_;
+ for (auto child : children)
+ shell_->OnInstanceError(child);
}
- void OnConnectionLost() {
- // Any time a Connector is lost or we lose the ShellClient connection, it
- // may have been the last pipe using this Instance. If so, clean up.
- if (connectors_.empty() && !shell_client_) {
- // Deletes |this|.
- shell_->OnInstanceError(this);
- }
+ Instance* parent() { return parent_; }
+ void AddChild(Instance* child) {
+ children_.insert(child);
+ child->parent_ = this;
}
-
- void OnInitializeResponse(mojom::ConnectorRequest connector_request) {
- if (connector_request.is_pending()) {
- connectors_.AddBinding(this, std::move(connector_request));
- connectors_.set_connection_error_handler(
- base::Bind(&Instance::OnConnectionLost, base::Unretained(this)));
- }
+ void RemoveChild(Instance* child) {
+ auto it = children_.find(child);
+ DCHECK(it != children_.end());
+ children_.erase(it);
+ child->parent_ = nullptr;
}
void ConnectToClient(scoped_ptr<ConnectParams> params) {
@@ -176,7 +173,8 @@ class Shell::Instance : public mojom::Connector,
CHECK(!shell_client_);
shell_client_ = std::move(client);
shell_client_.set_connection_error_handler(
- base::Bind(&Instance::OnShellClientLost, base::Unretained(this)));
+ base::Bind(&Instance::OnShellClientLost, base::Unretained(this),
+ shell_->GetWeakPtr()));
shell_client_->Initialize(mojom::Identity::From(identity_), id_,
base::Bind(&Instance::OnInitializeResponse,
base::Unretained(this)));
@@ -384,6 +382,29 @@ class Shell::Instance : public mojom::Connector,
shell_->NotifyPIDAvailable(id_, pid_);
}
+ void OnShellClientLost(base::WeakPtr<mojo::shell::Shell> shell) {
+ shell_client_.reset();
+ OnConnectionLost(shell);
+ }
+
+ void OnConnectionLost(base::WeakPtr<mojo::shell::Shell> shell) {
+ // Any time a Connector is lost or we lose the ShellClient connection, it
+ // may have been the last pipe using this Instance. If so, clean up.
+ if (shell && connectors_.empty() && !shell_client_) {
+ // Deletes |this|.
+ shell->OnInstanceError(this);
+ }
+ }
+
+ void OnInitializeResponse(mojom::ConnectorRequest connector_request) {
+ if (connector_request.is_pending()) {
+ connectors_.AddBinding(this, std::move(connector_request));
+ connectors_.set_connection_error_handler(
+ base::Bind(&Instance::OnConnectionLost, base::Unretained(this),
+ shell_->GetWeakPtr()));
+ }
+ }
+
mojo::shell::Shell* const shell_;
// An id that identifies this instance. Distinct from pid, as a single process
@@ -399,6 +420,8 @@ class Shell::Instance : public mojom::Connector,
BindingSet<mojom::Shell> shell_bindings_;
NativeRunner* runner_ = nullptr;
base::ProcessId pid_ = base::kNullProcessId;
+ Instance* parent_ = nullptr;
+ std::set<Instance*> children_;
base::WeakPtrFactory<Instance> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Instance);
@@ -425,9 +448,10 @@ Shell::Shell(scoped_ptr<NativeRunnerFactory> native_runner_factory,
weak_ptr_factory_(this) {
mojom::ShellClientPtr client;
mojom::ShellClientRequest request = GetProxy(&client);
- Instance* instance = CreateInstance(CreateShellIdentity(),
+ Instance* instance = CreateInstance(Identity(), CreateShellIdentity(),
GetPermissiveCapabilities());
instance->StartWithClient(std::move(client));
+ singletons_.insert(kShellName);
shell_connection_.reset(new ShellConnection(this, std::move(request)));
if (catalog)
@@ -467,7 +491,7 @@ mojom::ShellClientRequest Shell::InitInstanceForEmbedder(
void Shell::SetLoaderForName(scoped_ptr<Loader> loader,
const std::string& name) {
- NameToLoaderMap::iterator it = name_to_loader_.find(name);
+ auto it = name_to_loader_.find(name);
if (it != name_to_loader_.end())
delete it->second;
name_to_loader_[name] = loader.release();
@@ -496,8 +520,10 @@ bool Shell::AcceptConnection(Connection* connection) {
// Shell, private:
void Shell::InitCatalog(mojom::ShellClientPtr catalog) {
- Instance* instance =
- CreateInstance(CreateCatalogIdentity(), CapabilitySpec());
+ Instance* instance = CreateInstance(CreateShellIdentity(),
+ CreateCatalogIdentity(),
+ CapabilitySpec());
+ singletons_.insert(kCatalogName);
instance->StartWithClient(std::move(catalog));
// TODO(beng): this doesn't work anymore.
@@ -509,7 +535,9 @@ void Shell::InitCatalog(mojom::ShellClientPtr catalog) {
}
void Shell::TerminateShellConnections() {
- STLDeleteValues(&identity_to_instance_);
+ Instance* instance = GetExistingInstance(CreateShellIdentity());
+ DCHECK(instance);
+ OnInstanceError(instance);
}
void Shell::OnInstanceError(Instance* instance) {
@@ -588,12 +616,16 @@ bool Shell::ConnectToExistingInstance(scoped_ptr<ConnectParams>* params) {
return !!instance;
}
-Shell::Instance* Shell::CreateInstance(const Identity& target,
+Shell::Instance* Shell::CreateInstance(const Identity& source,
+ const Identity& target,
const CapabilitySpec& spec) {
CHECK(target.user_id() != mojom::kInheritUserID);
Instance* instance = new Instance(this, target, spec);
DCHECK(identity_to_instance_.find(target) ==
identity_to_instance_.end());
+ Instance* source_instance = GetExistingInstance(source);
+ if (source_instance)
+ source_instance->AddChild(instance);
identity_to_instance_[target] = instance;
mojom::InstanceInfoPtr info = instance->CreateInstanceInfo();
instance_listeners_.ForAllPtrs(
@@ -678,13 +710,16 @@ void Shell::OnGotResolvedName(mojom::ShellResolverPtr resolver,
capabilities = capabilities_ptr.To<CapabilitySpec>();
// Clients that request "all_users" class from the shell are allowed to
- // field connection requests from any user.
- if (HasClass(capabilities, kCapabilityClass_AllUsers))
+ // field connection requests from any user. They also run with a synthetic
+ // user id generated here. The user id provided via Connect() is ignored.
+ if (HasClass(capabilities, kCapabilityClass_AllUsers)) {
singletons_.insert(target.name());
+ target.set_user_id(base::GenerateGUID());
+ }
mojom::ClientProcessConnectionPtr client_process_connection =
params->TakeClientProcessConnection();
- Instance* instance = CreateInstance(target, capabilities);
+ Instance* instance = CreateInstance(params->source(), target, capabilities);
// Below are various paths through which a new Instance can be bound to a
// ShellClient proxy.
@@ -736,6 +771,10 @@ Loader* Shell::GetLoaderForName(const std::string& name) {
return default_loader_.get();
}
+base::WeakPtr<Shell> Shell::GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
void Shell::CleanupRunner(NativeRunner* runner) {
for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) {
if (it->get() == runner) {
« no previous file with comments | « mojo/shell/shell.h ('k') | mojo/shell/tests/connect/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698