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

Side by Side Diff: remoting/host/chromoting_host.cc

Issue 10572005: Use SingleThreadTaskRunner instead of MessageLoopProxy in remoting/host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "remoting/host/chromoting_host.h" 5 #include "remoting/host/chromoting_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 signal_strategy_(signal_strategy), 70 signal_strategy_(signal_strategy),
71 stopping_recorders_(0), 71 stopping_recorders_(0),
72 state_(kInitial), 72 state_(kInitial),
73 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), 73 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()),
74 login_backoff_(&kDefaultBackoffPolicy), 74 login_backoff_(&kDefaultBackoffPolicy),
75 authenticating_client_(false), 75 authenticating_client_(false),
76 reject_authenticating_client_(false) { 76 reject_authenticating_client_(false) {
77 DCHECK(context_); 77 DCHECK(context_);
78 DCHECK(signal_strategy); 78 DCHECK(signal_strategy);
79 DCHECK(desktop_environment_); 79 DCHECK(desktop_environment_);
80 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 80 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
81 } 81 }
82 82
83 ChromotingHost::~ChromotingHost() { 83 ChromotingHost::~ChromotingHost() {
84 DCHECK(clients_.empty()); 84 DCHECK(clients_.empty());
85 } 85 }
86 86
87 void ChromotingHost::Start() { 87 void ChromotingHost::Start() {
88 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 88 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
89 89
90 LOG(INFO) << "Starting host"; 90 LOG(INFO) << "Starting host";
91 91
92 // Make sure this object is not started. 92 // Make sure this object is not started.
93 if (state_ != kInitial) 93 if (state_ != kInitial)
94 return; 94 return;
95 state_ = kStarted; 95 state_ = kStarted;
96 96
97 // Start the SessionManager, supplying this ChromotingHost as the listener. 97 // Start the SessionManager, supplying this ChromotingHost as the listener.
98 session_manager_->Init(signal_strategy_, this); 98 session_manager_->Init(signal_strategy_, this);
99 } 99 }
100 100
101 // This method is called when we need to destroy the host process. 101 // This method is called when we need to destroy the host process.
102 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { 102 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) {
103 if (!context_->network_message_loop()->BelongsToCurrentThread()) { 103 if (!context_->network_task_runner()->BelongsToCurrentThread()) {
104 context_->network_message_loop()->PostTask( 104 context_->network_task_runner()->PostTask(
105 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); 105 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task));
106 return; 106 return;
107 } 107 }
108 108
109 // No-op if this object is not started yet. 109 // No-op if this object is not started yet.
110 if (state_ == kInitial || state_ == kStopped) { 110 if (state_ == kInitial || state_ == kStopped) {
111 // Nothing to do if we are not started. 111 // Nothing to do if we are not started.
112 state_ = kStopped; 112 state_ = kStopped;
113 context_->network_message_loop()->PostTask(FROM_HERE, shutdown_task); 113 context_->network_task_runner()->PostTask(FROM_HERE, shutdown_task);
114 return; 114 return;
115 } 115 }
116 if (!shutdown_task.is_null()) 116 if (!shutdown_task.is_null())
117 shutdown_tasks_.push_back(shutdown_task); 117 shutdown_tasks_.push_back(shutdown_task);
118 if (state_ == kStopping) 118 if (state_ == kStopping)
119 return; 119 return;
120 state_ = kStopping; 120 state_ = kStopping;
121 121
122 // Disconnect all of the clients, implicitly stopping the ScreenRecorder. 122 // Disconnect all of the clients, implicitly stopping the ScreenRecorder.
123 while (!clients_.empty()) { 123 while (!clients_.empty()) {
124 clients_.front()->Disconnect(); 124 clients_.front()->Disconnect();
125 } 125 }
126 126
127 // Destroy session manager. 127 // Destroy session manager.
128 session_manager_.reset(); 128 session_manager_.reset();
129 129
130 // Stop screen recorder 130 // Stop screen recorder
131 if (recorder_.get()) { 131 if (recorder_.get()) {
132 StopScreenRecorder(); 132 StopScreenRecorder();
133 } else if (!stopping_recorders_) { 133 } else if (!stopping_recorders_) {
134 ShutdownFinish(); 134 ShutdownFinish();
135 } 135 }
136 } 136 }
137 137
138 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { 138 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) {
139 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 139 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
140 status_observers_.AddObserver(observer); 140 status_observers_.AddObserver(observer);
141 } 141 }
142 142
143 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) { 143 void ChromotingHost::RemoveStatusObserver(HostStatusObserver* observer) {
144 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 144 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
145 status_observers_.RemoveObserver(observer); 145 status_observers_.RemoveObserver(observer);
146 } 146 }
147 147
148 void ChromotingHost::RejectAuthenticatingClient() { 148 void ChromotingHost::RejectAuthenticatingClient() {
149 DCHECK(authenticating_client_); 149 DCHECK(authenticating_client_);
150 reject_authenticating_client_ = true; 150 reject_authenticating_client_ = true;
151 } 151 }
152 152
153 void ChromotingHost::SetAuthenticatorFactory( 153 void ChromotingHost::SetAuthenticatorFactory(
154 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) { 154 scoped_ptr<protocol::AuthenticatorFactory> authenticator_factory) {
155 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 155 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
156 session_manager_->set_authenticator_factory(authenticator_factory.Pass()); 156 session_manager_->set_authenticator_factory(authenticator_factory.Pass());
157 } 157 }
158 158
159 //////////////////////////////////////////////////////////////////////////// 159 ////////////////////////////////////////////////////////////////////////////
160 // protocol::ClientSession::EventHandler implementation. 160 // protocol::ClientSession::EventHandler implementation.
161 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { 161 void ChromotingHost::OnSessionAuthenticated(ClientSession* client) {
162 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 162 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
163 163
164 login_backoff_.Reset(); 164 login_backoff_.Reset();
165 165
166 // Disconnect all other clients. 166 // Disconnect all other clients.
167 // Iterate over a copy of the list of clients, to avoid mutating the list 167 // Iterate over a copy of the list of clients, to avoid mutating the list
168 // while iterating over it. 168 // while iterating over it.
169 ClientList clients_copy(clients_); 169 ClientList clients_copy(clients_);
170 for (ClientList::const_iterator other_client = clients_copy.begin(); 170 for (ClientList::const_iterator other_client = clients_copy.begin();
171 other_client != clients_copy.end(); ++other_client) { 171 other_client != clients_copy.end(); ++other_client) {
172 if ((*other_client) != client) { 172 if ((*other_client) != client) {
(...skipping 14 matching lines...) Expand all
187 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 187 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
188 OnClientAuthenticated(jid)); 188 OnClientAuthenticated(jid));
189 authenticating_client_ = false; 189 authenticating_client_ = false;
190 190
191 if (reject_authenticating_client_) { 191 if (reject_authenticating_client_) {
192 client->Disconnect(); 192 client->Disconnect();
193 } 193 }
194 } 194 }
195 195
196 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { 196 void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) {
197 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 197 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
198 198
199 // Then we create a ScreenRecorder passing the message loops that 199 // Then we create a ScreenRecorder passing the message loops that
200 // it should run on. 200 // it should run on.
201 Encoder* encoder = CreateEncoder(client->connection()->session()->config()); 201 Encoder* encoder = CreateEncoder(client->connection()->session()->config());
202 202
203 recorder_ = new ScreenRecorder(context_->main_message_loop(), 203 recorder_ = new ScreenRecorder(context_->main_task_runner(),
204 context_->encode_message_loop(), 204 context_->encode_task_runner(),
205 context_->network_message_loop(), 205 context_->network_task_runner(),
206 desktop_environment_->capturer(), 206 desktop_environment_->capturer(),
207 encoder); 207 encoder);
208 208
209 // Immediately add the connection and start the session. 209 // Immediately add the connection and start the session.
210 recorder_->AddConnection(client->connection()); 210 recorder_->AddConnection(client->connection());
211 recorder_->Start(); 211 recorder_->Start();
212 desktop_environment_->OnSessionStarted(client->CreateClipboardProxy()); 212 desktop_environment_->OnSessionStarted(client->CreateClipboardProxy());
213 213
214 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 214 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
215 OnClientConnected(client->client_jid())); 215 OnClientConnected(client->client_jid()));
216 } 216 }
217 217
218 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { 218 void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) {
219 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 219 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
220 220
221 // Notify observers. 221 // Notify observers.
222 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 222 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
223 OnAccessDenied(client->client_jid())); 223 OnAccessDenied(client->client_jid()));
224 } 224 }
225 225
226 void ChromotingHost::OnSessionClosed(ClientSession* client) { 226 void ChromotingHost::OnSessionClosed(ClientSession* client) {
227 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 227 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
228 228
229 scoped_ptr<ClientSession> client_destroyer(client); 229 scoped_ptr<ClientSession> client_destroyer(client);
230 230
231 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); 231 ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client);
232 CHECK(it != clients_.end()); 232 CHECK(it != clients_.end());
233 clients_.erase(it); 233 clients_.erase(it);
234 234
235 if (recorder_.get()) { 235 if (recorder_.get()) {
236 recorder_->RemoveConnection(client->connection()); 236 recorder_->RemoveConnection(client->connection());
237 } 237 }
238 238
239 if (client->is_authenticated()) { 239 if (client->is_authenticated()) {
240 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 240 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
241 OnClientDisconnected(client->client_jid())); 241 OnClientDisconnected(client->client_jid()));
242 242
243 // TODO(sergeyu): This teardown logic belongs to ClientSession 243 // TODO(sergeyu): This teardown logic belongs to ClientSession
244 // class. It should start/stop screen recorder or tell the host 244 // class. It should start/stop screen recorder or tell the host
245 // when to do it. 245 // when to do it.
246 if (recorder_.get()) { 246 if (recorder_.get()) {
247 // Currently we don't allow more than one simultaneous connection, 247 // Currently we don't allow more than one simultaneous connection,
248 // so we need to shutdown recorder when a client disconnects. 248 // so we need to shutdown recorder when a client disconnects.
249 StopScreenRecorder(); 249 StopScreenRecorder();
250 } 250 }
251 desktop_environment_->OnSessionFinished(); 251 desktop_environment_->OnSessionFinished();
252 } 252 }
253 } 253 }
254 254
255 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, 255 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session,
256 int64 sequence_number) { 256 int64 sequence_number) {
257 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 257 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
258 if (recorder_.get()) 258 if (recorder_.get())
259 recorder_->UpdateSequenceNumber(sequence_number); 259 recorder_->UpdateSequenceNumber(sequence_number);
260 } 260 }
261 261
262 void ChromotingHost::OnSessionRouteChange( 262 void ChromotingHost::OnSessionRouteChange(
263 ClientSession* session, 263 ClientSession* session,
264 const std::string& channel_name, 264 const std::string& channel_name,
265 const protocol::TransportRoute& route) { 265 const protocol::TransportRoute& route) {
266 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 266 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
267 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 267 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
268 OnClientRouteChange(session->client_jid(), channel_name, 268 OnClientRouteChange(session->client_jid(), channel_name,
269 route)); 269 route));
270 } 270 }
271 271
272 void ChromotingHost::OnSessionManagerReady() { 272 void ChromotingHost::OnSessionManagerReady() {
273 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 273 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
274 // Don't need to do anything here, just wait for incoming 274 // Don't need to do anything here, just wait for incoming
275 // connections. 275 // connections.
276 } 276 }
277 277
278 void ChromotingHost::OnIncomingSession( 278 void ChromotingHost::OnIncomingSession(
279 protocol::Session* session, 279 protocol::Session* session,
280 protocol::SessionManager::IncomingSessionResponse* response) { 280 protocol::SessionManager::IncomingSessionResponse* response) {
281 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 281 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
282 282
283 if (state_ != kStarted) { 283 if (state_ != kStarted) {
284 *response = protocol::SessionManager::DECLINE; 284 *response = protocol::SessionManager::DECLINE;
285 return; 285 return;
286 } 286 }
287 287
288 if (login_backoff_.ShouldRejectRequest()) { 288 if (login_backoff_.ShouldRejectRequest()) {
289 *response = protocol::SessionManager::OVERLOAD; 289 *response = protocol::SessionManager::OVERLOAD;
290 return; 290 return;
291 } 291 }
(...skipping 22 matching lines...) Expand all
314 scoped_ptr<protocol::ConnectionToClient> connection( 314 scoped_ptr<protocol::ConnectionToClient> connection(
315 new protocol::ConnectionToClient(session)); 315 new protocol::ConnectionToClient(session));
316 ClientSession* client = new ClientSession( 316 ClientSession* client = new ClientSession(
317 this, connection.Pass(), desktop_environment_->event_executor(), 317 this, connection.Pass(), desktop_environment_->event_executor(),
318 desktop_environment_->capturer()); 318 desktop_environment_->capturer());
319 clients_.push_back(client); 319 clients_.push_back(client);
320 } 320 }
321 321
322 void ChromotingHost::set_protocol_config( 322 void ChromotingHost::set_protocol_config(
323 protocol::CandidateSessionConfig* config) { 323 protocol::CandidateSessionConfig* config) {
324 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 324 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
325 DCHECK(config); 325 DCHECK(config);
326 DCHECK_EQ(state_, kInitial); 326 DCHECK_EQ(state_, kInitial);
327 protocol_config_.reset(config); 327 protocol_config_.reset(config);
328 } 328 }
329 329
330 void ChromotingHost::OnLocalMouseMoved(const SkIPoint& new_pos) { 330 void ChromotingHost::OnLocalMouseMoved(const SkIPoint& new_pos) {
331 if (!context_->network_message_loop()->BelongsToCurrentThread()) { 331 if (!context_->network_task_runner()->BelongsToCurrentThread()) {
332 context_->network_message_loop()->PostTask( 332 context_->network_task_runner()->PostTask(
333 FROM_HERE, base::Bind(&ChromotingHost::OnLocalMouseMoved, 333 FROM_HERE, base::Bind(&ChromotingHost::OnLocalMouseMoved,
334 this, new_pos)); 334 this, new_pos));
335 return; 335 return;
336 } 336 }
337 337
338 ClientList::iterator client; 338 ClientList::iterator client;
339 for (client = clients_.begin(); client != clients_.end(); ++client) { 339 for (client = clients_.begin(); client != clients_.end(); ++client) {
340 (*client)->LocalMouseMoved(new_pos); 340 (*client)->LocalMouseMoved(new_pos);
341 } 341 }
342 } 342 }
343 343
344 void ChromotingHost::PauseSession(bool pause) { 344 void ChromotingHost::PauseSession(bool pause) {
345 if (!context_->network_message_loop()->BelongsToCurrentThread()) { 345 if (!context_->network_task_runner()->BelongsToCurrentThread()) {
346 context_->network_message_loop()->PostTask( 346 context_->network_task_runner()->PostTask(
347 FROM_HERE, base::Bind(&ChromotingHost::PauseSession, this, pause)); 347 FROM_HERE, base::Bind(&ChromotingHost::PauseSession, this, pause));
348 return; 348 return;
349 } 349 }
350 350
351 ClientList::iterator client; 351 ClientList::iterator client;
352 for (client = clients_.begin(); client != clients_.end(); ++client) { 352 for (client = clients_.begin(); client != clients_.end(); ++client) {
353 (*client)->SetDisableInputs(pause); 353 (*client)->SetDisableInputs(pause);
354 } 354 }
355 } 355 }
356 356
357 void ChromotingHost::DisconnectAllClients() { 357 void ChromotingHost::DisconnectAllClients() {
358 if (!context_->network_message_loop()->BelongsToCurrentThread()) { 358 if (!context_->network_task_runner()->BelongsToCurrentThread()) {
359 context_->network_message_loop()->PostTask( 359 context_->network_task_runner()->PostTask(
360 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this)); 360 FROM_HERE, base::Bind(&ChromotingHost::DisconnectAllClients, this));
361 return; 361 return;
362 } 362 }
363 363
364 while (!clients_.empty()) { 364 while (!clients_.empty()) {
365 size_t size = clients_.size(); 365 size_t size = clients_.size();
366 clients_.front()->Disconnect(); 366 clients_.front()->Disconnect();
367 CHECK_EQ(clients_.size(), size - 1); 367 CHECK_EQ(clients_.size(), size - 1);
368 } 368 }
369 } 369 }
370 370
371 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { 371 void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) {
372 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 372 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
373 DCHECK_EQ(state_, kInitial); 373 DCHECK_EQ(state_, kInitial);
374 374
375 ui_strings_ = ui_strings; 375 ui_strings_ = ui_strings;
376 } 376 }
377 377
378 // TODO(sergeyu): Move this to SessionManager? 378 // TODO(sergeyu): Move this to SessionManager?
379 // static 379 // static
380 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) { 380 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig& config) {
381 const protocol::ChannelConfig& video_config = config.video_config(); 381 const protocol::ChannelConfig& video_config = config.video_config();
382 382
383 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { 383 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) {
384 return EncoderRowBased::CreateVerbatimEncoder(); 384 return EncoderRowBased::CreateVerbatimEncoder();
385 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) { 385 } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) {
386 return EncoderRowBased::CreateZlibEncoder(); 386 return EncoderRowBased::CreateZlibEncoder();
387 } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) { 387 } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) {
388 return new remoting::EncoderVp8(); 388 return new remoting::EncoderVp8();
389 } 389 }
390 390
391 return NULL; 391 return NULL;
392 } 392 }
393 393
394 void ChromotingHost::StopScreenRecorder() { 394 void ChromotingHost::StopScreenRecorder() {
395 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 395 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
396 DCHECK(recorder_.get()); 396 DCHECK(recorder_.get());
397 397
398 ++stopping_recorders_; 398 ++stopping_recorders_;
399 scoped_refptr<ScreenRecorder> recorder = recorder_; 399 scoped_refptr<ScreenRecorder> recorder = recorder_;
400 recorder_ = NULL; 400 recorder_ = NULL;
401 recorder->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); 401 recorder->Stop(base::Bind(&ChromotingHost::OnScreenRecorderStopped, this));
402 } 402 }
403 403
404 void ChromotingHost::OnScreenRecorderStopped() { 404 void ChromotingHost::OnScreenRecorderStopped() {
405 if (!context_->network_message_loop()->BelongsToCurrentThread()) { 405 if (!context_->network_task_runner()->BelongsToCurrentThread()) {
406 context_->network_message_loop()->PostTask( 406 context_->network_task_runner()->PostTask(
407 FROM_HERE, base::Bind(&ChromotingHost::OnScreenRecorderStopped, this)); 407 FROM_HERE, base::Bind(&ChromotingHost::OnScreenRecorderStopped, this));
408 return; 408 return;
409 } 409 }
410 410
411 --stopping_recorders_; 411 --stopping_recorders_;
412 DCHECK_GE(stopping_recorders_, 0); 412 DCHECK_GE(stopping_recorders_, 0);
413 413
414 if (!stopping_recorders_ && state_ == kStopping) 414 if (!stopping_recorders_ && state_ == kStopping)
415 ShutdownFinish(); 415 ShutdownFinish();
416 } 416 }
417 417
418 void ChromotingHost::ShutdownFinish() { 418 void ChromotingHost::ShutdownFinish() {
419 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); 419 DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
420 DCHECK(!stopping_recorders_); 420 DCHECK(!stopping_recorders_);
421 421
422 state_ = kStopped; 422 state_ = kStopped;
423 423
424 // Keep reference to |this|, so that we don't get destroyed while 424 // Keep reference to |this|, so that we don't get destroyed while
425 // sending notifications. 425 // sending notifications.
426 scoped_refptr<ChromotingHost> self(this); 426 scoped_refptr<ChromotingHost> self(this);
427 427
428 // Notify observers. 428 // Notify observers.
429 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, 429 FOR_EACH_OBSERVER(HostStatusObserver, status_observers_,
430 OnShutdown()); 430 OnShutdown());
431 431
432 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); 432 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin();
433 it != shutdown_tasks_.end(); ++it) { 433 it != shutdown_tasks_.end(); ++it) {
434 it->Run(); 434 it->Run();
435 } 435 }
436 shutdown_tasks_.clear(); 436 shutdown_tasks_.clear();
437 } 437 }
438 438
439 } // namespace remoting 439 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | remoting/host/chromoting_host_context.h » ('j') | remoting/host/chromoting_host_context.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698