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

Side by Side Diff: components/arc/arc_bridge_service_impl.cc

Issue 2194193002: Fix ArcBridgeBootstrap race issues. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments. Created 4 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/arc/arc_bridge_service_impl.h" 5 #include "components/arc/arc_bridge_service_impl.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/json/json_writer.h" 11 #include "base/json/json_writer.h"
12 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
13 #include "base/sequenced_task_runner.h" 13 #include "base/sequenced_task_runner.h"
14 #include "base/sys_info.h" 14 #include "base/sys_info.h"
15 #include "base/task_runner_util.h" 15 #include "base/task_runner_util.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "chromeos/chromeos_switches.h" 18 #include "chromeos/chromeos_switches.h"
19 #include "chromeos/dbus/dbus_method_call_status.h" 19 #include "chromeos/dbus/dbus_method_call_status.h"
20 #include "chromeos/dbus/dbus_thread_manager.h" 20 #include "chromeos/dbus/dbus_thread_manager.h"
21 #include "chromeos/dbus/session_manager_client.h"
22 #include "components/arc/arc_bridge_host_impl.h" 21 #include "components/arc/arc_bridge_host_impl.h"
23 #include "components/prefs/pref_registry_simple.h" 22 #include "components/prefs/pref_registry_simple.h"
24 #include "components/prefs/pref_service.h" 23 #include "components/prefs/pref_service.h"
25 24
26 namespace arc { 25 namespace arc {
27 26
28 extern ArcBridgeService* g_arc_bridge_service; 27 extern ArcBridgeService* g_arc_bridge_service;
29 28
30 namespace { 29 namespace {
31 constexpr int64_t kReconnectDelayInSeconds = 5; 30 constexpr int64_t kReconnectDelayInSeconds = 5;
32 } // namespace 31 } // namespace
33 32
34 ArcBridgeServiceImpl::ArcBridgeServiceImpl( 33 ArcBridgeServiceImpl::ArcBridgeServiceImpl()
35 std::unique_ptr<ArcBridgeBootstrap> bootstrap) 34 : session_started_(false),
36 : bootstrap_(std::move(bootstrap)), 35 factory_(base::Bind(ArcBridgeBootstrap::Create)),
37 session_started_(false),
38 weak_factory_(this) { 36 weak_factory_(this) {
39 DCHECK(!g_arc_bridge_service); 37 DCHECK(!g_arc_bridge_service);
40 g_arc_bridge_service = this; 38 g_arc_bridge_service = this;
41 bootstrap_->set_delegate(this);
42 } 39 }
43 40
44 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() { 41 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() {
45 DCHECK(g_arc_bridge_service == this); 42 DCHECK(g_arc_bridge_service == this);
46 g_arc_bridge_service = nullptr; 43 g_arc_bridge_service = nullptr;
47 } 44 }
48 45
49 void ArcBridgeServiceImpl::HandleStartup() { 46 void ArcBridgeServiceImpl::HandleStartup() {
50 DCHECK(CalledOnValidThread()); 47 DCHECK(CalledOnValidThread());
51 if (session_started_) 48 if (session_started_)
(...skipping 19 matching lines...) Expand all
71 void ArcBridgeServiceImpl::PrerequisitesChanged() { 68 void ArcBridgeServiceImpl::PrerequisitesChanged() {
72 DCHECK(CalledOnValidThread()); 69 DCHECK(CalledOnValidThread());
73 VLOG(1) << "Prerequisites changed. " 70 VLOG(1) << "Prerequisites changed. "
74 << "state=" << static_cast<uint32_t>(state()) 71 << "state=" << static_cast<uint32_t>(state())
75 << ", session_started=" << session_started_; 72 << ", session_started=" << session_started_;
76 if (state() == State::STOPPED) { 73 if (state() == State::STOPPED) {
77 if (!session_started_) 74 if (!session_started_)
78 return; 75 return;
79 VLOG(0) << "Prerequisites met, starting ARC"; 76 VLOG(0) << "Prerequisites met, starting ARC";
80 SetStopReason(StopReason::SHUTDOWN); 77 SetStopReason(StopReason::SHUTDOWN);
78
81 SetState(State::CONNECTING); 79 SetState(State::CONNECTING);
80 bootstrap_ = factory_.Run();
81 bootstrap_->set_delegate(this);
82 bootstrap_->Start(); 82 bootstrap_->Start();
83 } else { 83 } else {
84 if (session_started_) 84 if (session_started_)
85 return; 85 return;
86 VLOG(0) << "Prerequisites stopped being met, stopping ARC"; 86 VLOG(0) << "Prerequisites stopped being met, stopping ARC";
87 StopInstance(); 87 StopInstance();
88 } 88 }
89 } 89 }
90 90
91 void ArcBridgeServiceImpl::StopInstance() { 91 void ArcBridgeServiceImpl::StopInstance() {
92 DCHECK(CalledOnValidThread()); 92 DCHECK(CalledOnValidThread());
93 if (state() == State::STOPPED || state() == State::STOPPING) { 93 if (state() == State::STOPPED || state() == State::STOPPING) {
94 VLOG(1) << "StopInstance() called when ARC is not running"; 94 VLOG(1) << "StopInstance() called when ARC is not running";
95 return; 95 return;
96 } 96 }
97 97
98 // We were explicitly asked to stop, so do not reconnect.
99 reconnect_ = false;
100
98 VLOG(1) << "Stopping ARC"; 101 VLOG(1) << "Stopping ARC";
102 DCHECK(bootstrap_.get());
99 SetState(State::STOPPING); 103 SetState(State::STOPPING);
100 arc_bridge_host_.reset(); 104 arc_bridge_host_.reset();
105
106 // Note: this can call OnStopped() internally as a callback.
101 bootstrap_->Stop(); 107 bootstrap_->Stop();
102
103 // We were explicitly asked to stop, so do not reconnect.
104 reconnect_ = false;
105 } 108 }
106 109
107 void ArcBridgeServiceImpl::OnConnectionEstablished( 110 void ArcBridgeServiceImpl::OnConnectionEstablished(
108 mojom::ArcBridgeInstancePtr instance) { 111 mojom::ArcBridgeInstancePtr instance) {
109 DCHECK(CalledOnValidThread()); 112 DCHECK(CalledOnValidThread());
110 if (state() != State::CONNECTING) { 113 if (state() != State::CONNECTING) {
111 VLOG(1) << "StopInstance() called while connecting"; 114 VLOG(1) << "StopInstance() called while connecting";
112 return; 115 return;
113 } 116 }
114 117
115 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance))); 118 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance)));
116 119
117 // The container can be considered to have been successfully launched, so 120 // The container can be considered to have been successfully launched, so
118 // restart if the connection goes down without being requested. 121 // restart if the connection goes down without being requested.
119 reconnect_ = true; 122 reconnect_ = true;
120 VLOG(0) << "ARC ready"; 123 VLOG(0) << "ARC ready";
121 SetState(State::READY); 124 SetState(State::READY);
122 } 125 }
123 126
124 void ArcBridgeServiceImpl::OnStopped(StopReason stop_reason) { 127 void ArcBridgeServiceImpl::OnStopped(StopReason stop_reason) {
125 DCHECK(CalledOnValidThread()); 128 DCHECK(CalledOnValidThread());
129 VLOG(0) << "ARC stopped: " << static_cast<int>(stop_reason);
Luis Héctor Chávez 2016/09/15 23:08:49 Can we have an operator<< for StopReason? That'll
hidehiko 2016/09/20 13:35:19 Done.
126 arc_bridge_host_.reset(); 130 arc_bridge_host_.reset();
131 bootstrap_.reset();
127 SetStopReason(stop_reason); 132 SetStopReason(stop_reason);
128 SetState(State::STOPPED); 133 SetState(State::STOPPED);
129 VLOG(0) << "ARC stopped";
130 134
131 if (reconnect_) { 135 if (reconnect_) {
132 // There was a previous invocation and it crashed for some reason. Try 136 // There was a previous invocation and it crashed for some reason. Try
133 // starting the container again. 137 // starting the container again.
134 reconnect_ = false; 138 reconnect_ = false;
135 VLOG(0) << "ARC reconnecting"; 139 VLOG(0) << "ARC reconnecting";
136 if (use_delay_before_reconnecting_) { 140 if (use_delay_before_reconnecting_) {
137 // Instead of immediately trying to restart the container, give it some 141 // Instead of immediately trying to restart the container, give it some
138 // time to finish tearing down in case it is still in the process of 142 // time to finish tearing down in case it is still in the process of
139 // stopping. 143 // stopping.
140 base::MessageLoop::current()->task_runner()->PostDelayedTask( 144 base::MessageLoop::current()->task_runner()->PostDelayedTask(
141 FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged, 145 FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged,
142 weak_factory_.GetWeakPtr()), 146 weak_factory_.GetWeakPtr()),
143 base::TimeDelta::FromSeconds(kReconnectDelayInSeconds)); 147 base::TimeDelta::FromSeconds(kReconnectDelayInSeconds));
144 } else { 148 } else {
145 // Restart immediately. 149 // Restart immediately.
146 PrerequisitesChanged(); 150 PrerequisitesChanged();
147 } 151 }
148 } 152 }
149 } 153 }
150 154
151 } // namespace arc 155 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698