Chromium Code Reviews| Index: components/arc/arc_bridge_service_impl.cc |
| diff --git a/components/arc/arc_bridge_service_impl.cc b/components/arc/arc_bridge_service_impl.cc |
| index fbc8f0b08218bc6e2312da5d545ddd5e12d23381..0fb2b8d42d8bb0dbe2469dc2df6482e258c4ca81 100644 |
| --- a/components/arc/arc_bridge_service_impl.cc |
| +++ b/components/arc/arc_bridge_service_impl.cc |
| @@ -23,12 +23,16 @@ |
| namespace arc { |
| namespace { |
|
Luis Héctor Chávez
2016/12/16 23:02:13
nit: maybe add a newline before for consistency?
hidehiko
2016/12/19 07:41:21
Done.
|
| -constexpr int64_t kReconnectDelayInSeconds = 5; |
| + |
| +constexpr base::TimeDelta kDefaultRestartDelay = |
| + base::TimeDelta::FromSeconds(5); |
| + |
| } // namespace |
| ArcBridgeServiceImpl::ArcBridgeServiceImpl( |
| const scoped_refptr<base::TaskRunner>& blocking_task_runner) |
| : session_started_(false), |
| + restart_delay_(kDefaultRestartDelay), |
| factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)), |
| weak_factory_(this) {} |
| @@ -57,13 +61,15 @@ void ArcBridgeServiceImpl::RequestStop() { |
| void ArcBridgeServiceImpl::OnShutdown() { |
| DCHECK(CalledOnValidThread()); |
| + |
| VLOG(1) << "OnShutdown"; |
| - if (!session_started_) |
| - return; |
| session_started_ = false; |
| - reconnect_ = false; |
| + restart_timer_.Stop(); |
| if (arc_session_) |
| arc_session_->OnShutdown(); |
| + // ArcSession::OnShutdown() invokes OnSessionStopped() synchronously. |
| + // In the observer method, |arc_session_| should be destroyed. |
| + DCHECK(!arc_session_); |
| } |
| void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting( |
| @@ -72,8 +78,12 @@ void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting( |
| factory_ = factory; |
| } |
| -void ArcBridgeServiceImpl::DisableReconnectDelayForTesting() { |
| - use_delay_before_reconnecting_ = false; |
| +void ArcBridgeServiceImpl::SetRestartDelayForTesting( |
| + const base::TimeDelta& restart_delay) { |
| + DCHECK_EQ(state(), State::STOPPED); |
| + DCHECK(!arc_session_); |
| + DCHECK(!restart_timer_.IsRunning()); |
| + restart_delay_ = restart_delay; |
| } |
| void ArcBridgeServiceImpl::PrerequisitesChanged() { |
|
Luis Héctor Chávez
2016/12/16 23:02:13
Now that you've removed the third caller of Prereq
Luis Héctor Chávez
2016/12/16 23:06:35
Nevermind about this, I just saw your second patch
hidehiko
2016/12/19 07:41:21
Yes. Let me work on it in the following CL.
|
| @@ -82,19 +92,16 @@ void ArcBridgeServiceImpl::PrerequisitesChanged() { |
| << "state=" << static_cast<uint32_t>(state()) |
| << ", session_started=" << session_started_; |
| if (state() == State::STOPPED) { |
| - if (!session_started_) |
| + if (!session_started_) { |
| + // We were explicitly asked to stop, so do not restart. |
| + restart_timer_.Stop(); |
|
Luis Héctor Chávez
2016/12/16 23:02:13
How about you move this to L96-97 to RequestStop()
hidehiko
2016/12/19 07:41:21
If this is not a big problem, can I keep this in t
|
| return; |
| + } |
| + DCHECK(!restart_timer_.IsRunning()); |
|
Luis Héctor Chávez
2016/12/16 23:02:13
Both branches check for this. Move to after L93?
hidehiko
2016/12/19 07:41:21
Similar to above, can I address this in the follow
|
| VLOG(0) << "Prerequisites met, starting ARC"; |
| - SetStopReason(StopReason::SHUTDOWN); |
| - |
| - if (arc_session_) |
| - arc_session_->RemoveObserver(this); |
| - |
| - SetState(State::CONNECTING); |
| - arc_session_ = factory_.Run(); |
| - arc_session_->AddObserver(this); |
| - arc_session_->Start(); |
| + StartArcSession(); |
| } else { |
| + DCHECK(!restart_timer_.IsRunning()); |
| if (session_started_) |
| return; |
| VLOG(0) << "Prerequisites stopped being met, stopping ARC"; |
| @@ -102,16 +109,30 @@ void ArcBridgeServiceImpl::PrerequisitesChanged() { |
| } |
| } |
| +void ArcBridgeServiceImpl::StartArcSession() { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK_EQ(state(), State::STOPPED); |
| + DCHECK(!arc_session_); |
| + DCHECK(!restart_timer_.IsRunning()); |
| + |
| + VLOG(1) << "Starting ARC instance"; |
| + SetStopReason(StopReason::SHUTDOWN); |
| + arc_session_ = factory_.Run(); |
| + arc_session_->AddObserver(this); |
| + SetState(State::CONNECTING); |
| + arc_session_->Start(); |
| +} |
| + |
| void ArcBridgeServiceImpl::StopInstance() { |
| DCHECK(CalledOnValidThread()); |
| - if (state() == State::STOPPED || state() == State::STOPPING) { |
| + DCHECK_NE(state(), State::STOPPED); |
| + DCHECK(!restart_timer_.IsRunning()); |
| + |
| + if (state() == State::STOPPING) { |
| VLOG(1) << "StopInstance() called when ARC is not running"; |
| return; |
| } |
| - // We were explicitly asked to stop, so do not reconnect. |
| - reconnect_ = false; |
| - |
| VLOG(1) << "Stopping ARC"; |
| DCHECK(arc_session_.get()); |
| SetState(State::STOPPING); |
| @@ -127,39 +148,38 @@ void ArcBridgeServiceImpl::OnSessionReady() { |
| return; |
| } |
| - // The container can be considered to have been successfully launched, so |
| - // restart if the connection goes down without being requested. |
| - reconnect_ = true; |
| VLOG(0) << "ARC ready"; |
| SetState(State::READY); |
| } |
| void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) { |
| DCHECK(CalledOnValidThread()); |
| + DCHECK(!restart_timer_.IsRunning()); |
| + |
| VLOG(0) << "ARC stopped: " << stop_reason; |
| arc_session_->RemoveObserver(this); |
| arc_session_.reset(); |
| - SetStopReason(stop_reason); |
| - SetState(State::STOPPED); |
| - if (reconnect_) { |
| + // If READY, ARC instance is unexpectedly crashed so we need to restart it |
|
Luis Héctor Chávez
2016/12/16 23:02:13
nit: "ARC instance unexpectedly crashed".
hidehiko
2016/12/19 07:41:21
Done.
|
| + // automatically. If STOPPING, it is the result of consecutive RequestStop() |
| + // followed by RequestStart() invocation. |
| + // If CONNECTING, ARC instance has not been booted properly, so do not |
| + // restart it automatically. |
| + if (session_started_ && |
|
Luis Héctor Chávez
2016/12/16 23:02:13
In the same spirit as we did reset |reconnect_|, s
hidehiko
2016/12/19 07:41:21
IIUC, unlike |reconnect_|, |session_started_| shou
Luis Héctor Chávez
2016/12/19 22:23:38
I like the proposed condition much better, since i
hidehiko
2016/12/20 13:38:02
Sure, done. Just in case, could you take another l
|
| + (state() == State::READY || state() == State::STOPPING)) { |
| // There was a previous invocation and it crashed for some reason. Try |
| - // starting the container again. |
| - reconnect_ = false; |
| - VLOG(0) << "ARC reconnecting"; |
| - if (use_delay_before_reconnecting_) { |
| - // Instead of immediately trying to restart the container, give it some |
| - // time to finish tearing down in case it is still in the process of |
| - // stopping. |
| - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| - FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged, |
| - weak_factory_.GetWeakPtr()), |
| - base::TimeDelta::FromSeconds(kReconnectDelayInSeconds)); |
| - } else { |
| - // Restart immediately. |
| - PrerequisitesChanged(); |
| - } |
| + // starting ARC instance later again. |
| + // Note that even |restart_delay_| is 0 (for testing), it needs to |
| + // PostTask, because observer callback may call RequestStart()/Stop(), |
| + // which can change restarting. |
| + VLOG(0) << "ARC restarting"; |
| + restart_timer_.Start(FROM_HERE, restart_delay_, |
| + base::Bind(&ArcBridgeServiceImpl::StartArcSession, |
| + weak_factory_.GetWeakPtr())); |
| } |
| + |
| + SetStopReason(stop_reason); |
| + SetState(State::STOPPED); |
| } |
| } // namespace arc |