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

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: rebase 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), weak_factory_(this) {
36 : bootstrap_(std::move(bootstrap)),
37 session_started_(false),
38 weak_factory_(this) {
39 DCHECK(!g_arc_bridge_service); 35 DCHECK(!g_arc_bridge_service);
40 g_arc_bridge_service = this; 36 g_arc_bridge_service = this;
41 bootstrap_->set_delegate(this);
42 } 37 }
43 38
44 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() { 39 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() {
45 DCHECK(g_arc_bridge_service == this); 40 DCHECK(g_arc_bridge_service == this);
46 g_arc_bridge_service = nullptr; 41 g_arc_bridge_service = nullptr;
47 } 42 }
48 43
49 void ArcBridgeServiceImpl::HandleStartup() { 44 void ArcBridgeServiceImpl::HandleStartup() {
50 DCHECK(CalledOnValidThread()); 45 DCHECK(CalledOnValidThread());
51 if (session_started_) 46 if (session_started_)
(...skipping 19 matching lines...) Expand all
71 void ArcBridgeServiceImpl::PrerequisitesChanged() { 66 void ArcBridgeServiceImpl::PrerequisitesChanged() {
72 DCHECK(CalledOnValidThread()); 67 DCHECK(CalledOnValidThread());
73 VLOG(1) << "Prerequisites changed. " 68 VLOG(1) << "Prerequisites changed. "
74 << "state=" << static_cast<uint32_t>(state()) 69 << "state=" << static_cast<uint32_t>(state())
75 << ", session_started=" << session_started_; 70 << ", session_started=" << session_started_;
76 if (state() == State::STOPPED) { 71 if (state() == State::STOPPED) {
77 if (!session_started_) 72 if (!session_started_)
78 return; 73 return;
79 VLOG(0) << "Prerequisites met, starting ARC"; 74 VLOG(0) << "Prerequisites met, starting ARC";
80 SetStopReason(StopReason::SHUTDOWN); 75 SetStopReason(StopReason::SHUTDOWN);
76
81 SetState(State::CONNECTING); 77 SetState(State::CONNECTING);
78 bootstrap_ =
79 delegate_ ? delegate_->CreateBootstrap() : ArcBridgeBootstrap::Create();
80 bootstrap_->set_delegate(this);
82 bootstrap_->Start(); 81 bootstrap_->Start();
83 } else { 82 } else {
84 if (session_started_) 83 if (session_started_)
85 return; 84 return;
86 VLOG(0) << "Prerequisites stopped being met, stopping ARC"; 85 VLOG(0) << "Prerequisites stopped being met, stopping ARC";
87 StopInstance(); 86 StopInstance();
88 } 87 }
89 } 88 }
90 89
91 void ArcBridgeServiceImpl::StopInstance() { 90 void ArcBridgeServiceImpl::StopInstance() {
92 DCHECK(CalledOnValidThread()); 91 DCHECK(CalledOnValidThread());
93 if (state() == State::STOPPED || state() == State::STOPPING) { 92 if (state() == State::STOPPED || state() == State::STOPPING) {
94 VLOG(1) << "StopInstance() called when ARC is not running"; 93 VLOG(1) << "StopInstance() called when ARC is not running";
95 return; 94 return;
96 } 95 }
97 96
97 // We were explicitly asked to stop, so do not reconnect.
98 reconnect_ = false;
99
98 VLOG(1) << "Stopping ARC"; 100 VLOG(1) << "Stopping ARC";
101 DCHECK(bootstrap_.get());
99 SetState(State::STOPPING); 102 SetState(State::STOPPING);
100 arc_bridge_host_.reset(); 103 arc_bridge_host_.reset();
104
105 // Note: this can call OnStopped() internally as a callback.
101 bootstrap_->Stop(); 106 bootstrap_->Stop();
102
103 // We were explicitly asked to stop, so do not reconnect.
104 reconnect_ = false;
105 } 107 }
106 108
107 void ArcBridgeServiceImpl::OnConnectionEstablished( 109 void ArcBridgeServiceImpl::OnConnectionEstablished(
108 mojom::ArcBridgeInstancePtr instance) { 110 mojom::ArcBridgeInstancePtr instance) {
109 DCHECK(CalledOnValidThread()); 111 DCHECK(CalledOnValidThread());
110 if (state() != State::CONNECTING) { 112 if (state() != State::CONNECTING) {
111 VLOG(1) << "StopInstance() called while connecting"; 113 VLOG(1) << "StopInstance() called while connecting";
112 return; 114 return;
113 } 115 }
114 116
115 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance))); 117 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance)));
116 118
117 // The container can be considered to have been successfully launched, so 119 // The container can be considered to have been successfully launched, so
118 // restart if the connection goes down without being requested. 120 // restart if the connection goes down without being requested.
119 reconnect_ = true; 121 reconnect_ = true;
120 VLOG(0) << "ARC ready"; 122 VLOG(0) << "ARC ready";
121 SetState(State::READY); 123 SetState(State::READY);
122 } 124 }
123 125
124 void ArcBridgeServiceImpl::OnStopped(StopReason stop_reason) { 126 void ArcBridgeServiceImpl::OnStopped(StopReason stop_reason) {
125 DCHECK(CalledOnValidThread()); 127 DCHECK(CalledOnValidThread());
128 VLOG(0) << "ARC stopped: " << static_cast<int>(stop_reason);
126 arc_bridge_host_.reset(); 129 arc_bridge_host_.reset();
130 bootstrap_.reset();
127 SetStopReason(stop_reason); 131 SetStopReason(stop_reason);
128 SetState(State::STOPPED); 132 SetState(State::STOPPED);
129 VLOG(0) << "ARC stopped";
130 133
131 if (reconnect_) { 134 if (reconnect_) {
132 // There was a previous invocation and it crashed for some reason. Try 135 // There was a previous invocation and it crashed for some reason. Try
133 // starting the container again. 136 // starting the container again.
134 reconnect_ = false; 137 reconnect_ = false;
135 VLOG(0) << "ARC reconnecting"; 138 VLOG(0) << "ARC reconnecting";
136 if (use_delay_before_reconnecting_) { 139 if (use_delay_before_reconnecting_) {
137 // Instead of immediately trying to restart the container, give it some 140 // 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 141 // time to finish tearing down in case it is still in the process of
139 // stopping. 142 // stopping.
140 base::MessageLoop::current()->task_runner()->PostDelayedTask( 143 base::MessageLoop::current()->task_runner()->PostDelayedTask(
141 FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged, 144 FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged,
142 weak_factory_.GetWeakPtr()), 145 weak_factory_.GetWeakPtr()),
143 base::TimeDelta::FromSeconds(kReconnectDelayInSeconds)); 146 base::TimeDelta::FromSeconds(kReconnectDelayInSeconds));
144 } else { 147 } else {
145 // Restart immediately. 148 // Restart immediately.
146 PrerequisitesChanged(); 149 PrerequisitesChanged();
147 } 150 }
148 } 151 }
149 } 152 }
150 153
151 } // namespace arc 154 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698