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

Side by Side Diff: chrome/browser/sync/glue/sync_backend_host.cc

Issue 23189021: sync: Gracefully handle very early shutdown (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Retry: sync non-blocking early shutdown Created 7 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 | 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 "chrome/browser/sync/glue/sync_backend_host.h" 5 #include "chrome/browser/sync/glue/sync_backend_host.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 // This includes refreshing encryption, setting up the device info change 191 // This includes refreshing encryption, setting up the device info change
192 // processor, etc. 192 // processor, etc.
193 void DoInitialProcessControlTypes(); 193 void DoInitialProcessControlTypes();
194 194
195 // Some parts of DoInitialProcessControlTypes() may be executed on a different 195 // Some parts of DoInitialProcessControlTypes() may be executed on a different
196 // thread. This function asynchronously continues the work started in 196 // thread. This function asynchronously continues the work started in
197 // DoInitialProcessControlTypes() once that other thread gets back to us. 197 // DoInitialProcessControlTypes() once that other thread gets back to us.
198 void DoFinishInitialProcessControlTypes(); 198 void DoFinishInitialProcessControlTypes();
199 199
200 // The shutdown order is a bit complicated: 200 // The shutdown order is a bit complicated:
201 // 1) Call DoStopSyncManagerForShutdown() from |frontend_loop_| to request 201 // 1) Call the SyncManagerStopHandle's RequestStop() from |frontend_loop_| to
202 // sync manager to stop as soon as possible. 202 // request sync manager to stop as soon as possible.
203 // 2) Post DoShutdown() to sync loop to clean up backend state, save 203 // 2) Post DoShutdown() to sync loop to clean up backend state, save
204 // directory and destroy sync manager. 204 // directory and destroy sync manager.
205 void DoStopSyncManagerForShutdown(); 205 void DoShutdown(bool sync_disabled,
206 void DoShutdown(bool sync_disabled); 206 scoped_ptr<syncer::CancelationSignal> signal);
207 void DoDestroySyncManager(); 207 void DoDestroySyncManager();
208 208
209 // Configuration methods that must execute on sync loop. 209 // Configuration methods that must execute on sync loop.
210 void DoConfigureSyncer( 210 void DoConfigureSyncer(
211 syncer::ConfigureReason reason, 211 syncer::ConfigureReason reason,
212 const DoConfigureSyncerTypes& config_types, 212 const DoConfigureSyncerTypes& config_types,
213 const syncer::ModelSafeRoutingInfo routing_info, 213 const syncer::ModelSafeRoutingInfo routing_info,
214 const base::Callback<void(syncer::ModelTypeSet, 214 const base::Callback<void(syncer::ModelTypeSet,
215 syncer::ModelTypeSet)>& ready_task, 215 syncer::ModelTypeSet)>& ready_task,
216 const base::Closure& retry_callback); 216 const base::Closure& retry_callback);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 profile_(profile), 298 profile_(profile),
299 name_(name), 299 name_(name),
300 core_(new Core(name_, profile_->GetPath().Append(kSyncDataFolderName), 300 core_(new Core(name_, profile_->GetPath().Append(kSyncDataFolderName),
301 weak_ptr_factory_.GetWeakPtr())), 301 weak_ptr_factory_.GetWeakPtr())),
302 initialization_state_(NOT_ATTEMPTED), 302 initialization_state_(NOT_ATTEMPTED),
303 sync_prefs_(sync_prefs), 303 sync_prefs_(sync_prefs),
304 frontend_(NULL), 304 frontend_(NULL),
305 cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE), 305 cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE),
306 invalidator_( 306 invalidator_(
307 invalidation::InvalidationServiceFactory::GetForProfile(profile)), 307 invalidation::InvalidationServiceFactory::GetForProfile(profile)),
308 invalidation_handler_registered_(false) { 308 invalidation_handler_registered_(false),
309 cancelation_signal_(new syncer::CancelationSignal()) {
309 } 310 }
310 311
311 SyncBackendHost::SyncBackendHost(Profile* profile) 312 SyncBackendHost::SyncBackendHost(Profile* profile)
312 : weak_ptr_factory_(this), 313 : weak_ptr_factory_(this),
313 frontend_loop_(base::MessageLoop::current()), 314 frontend_loop_(base::MessageLoop::current()),
314 profile_(profile), 315 profile_(profile),
315 name_("Unknown"), 316 name_("Unknown"),
316 initialization_state_(NOT_ATTEMPTED), 317 initialization_state_(NOT_ATTEMPTED),
317 frontend_(NULL), 318 frontend_(NULL),
318 cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE), 319 cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE),
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 credentials, 395 credentials,
395 invalidator_->GetInvalidatorClientId(), 396 invalidator_->GetInvalidatorClientId(),
396 sync_manager_factory.Pass(), 397 sync_manager_factory.Pass(),
397 delete_sync_data_folder, 398 delete_sync_data_folder,
398 sync_prefs_->GetEncryptionBootstrapToken(), 399 sync_prefs_->GetEncryptionBootstrapToken(),
399 sync_prefs_->GetKeystoreEncryptionBootstrapToken(), 400 sync_prefs_->GetKeystoreEncryptionBootstrapToken(),
400 scoped_ptr<InternalComponentsFactory>( 401 scoped_ptr<InternalComponentsFactory>(
401 new InternalComponentsFactoryImpl(factory_switches)).Pass(), 402 new InternalComponentsFactoryImpl(factory_switches)).Pass(),
402 unrecoverable_error_handler.Pass(), 403 unrecoverable_error_handler.Pass(),
403 report_unrecoverable_error_function, 404 report_unrecoverable_error_function,
404 !cl->HasSwitch(switches::kSyncDisableOAuth2Token))); 405 !cl->HasSwitch(switches::kSyncDisableOAuth2Token),
406 cancelation_signal_.get()));
405 InitCore(init_opts.Pass()); 407 InitCore(init_opts.Pass());
406 } 408 }
407 409
408 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) { 410 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) {
409 DCHECK(registrar_->sync_thread()->IsRunning()); 411 DCHECK(registrar_->sync_thread()->IsRunning());
410 registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE, 412 registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
411 base::Bind(&SyncBackendHost::Core::DoUpdateCredentials, 413 base::Bind(&SyncBackendHost::Core::DoUpdateCredentials,
412 core_.get(), 414 core_.get(),
413 credentials)); 415 credentials));
414 } 416 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 // clicks OK, immediately reopens the advanced settings dialog, and gets an 487 // clicks OK, immediately reopens the advanced settings dialog, and gets an
486 // unnecessary prompt for a passphrase. 488 // unnecessary prompt for a passphrase.
487 // Note: It is not guaranteed that the passphrase will be accepted by the 489 // Note: It is not guaranteed that the passphrase will be accepted by the
488 // syncer thread, since we could receive a new nigori node while the task is 490 // syncer thread, since we could receive a new nigori node while the task is
489 // pending. This scenario is a valid race, and SetDecryptionPassphrase can 491 // pending. This scenario is a valid race, and SetDecryptionPassphrase can
490 // trigger a new OnPassphraseRequired if it needs to. 492 // trigger a new OnPassphraseRequired if it needs to.
491 NotifyPassphraseAccepted(); 493 NotifyPassphraseAccepted();
492 return true; 494 return true;
493 } 495 }
494 496
495 void SyncBackendHost::StopSyncManagerForShutdown() {
496 DCHECK_GT(initialization_state_, NOT_ATTEMPTED);
497 if (initialization_state_ == CREATING_SYNC_MANAGER) {
498 // We post here to implicitly wait for the SyncManager to be created,
499 // if needed. We have to wait, since we need to shutdown immediately,
500 // and we need to tell the SyncManager so it can abort any activity
501 // (net I/O, data application).
502 DCHECK(registrar_->sync_thread()->IsRunning());
503 registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
504 base::Bind(&SyncBackendHost::Core::DoStopSyncManagerForShutdown,
505 core_.get()));
506 } else {
507 core_->DoStopSyncManagerForShutdown();
508 }
509 }
510
511 void SyncBackendHost::StopSyncingForShutdown() { 497 void SyncBackendHost::StopSyncingForShutdown() {
512 DCHECK_EQ(base::MessageLoop::current(), frontend_loop_); 498 DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
499 DCHECK_GT(initialization_state_, NOT_ATTEMPTED);
513 500
514 // Immediately stop sending messages to the frontend. 501 // Immediately stop sending messages to the frontend.
515 frontend_ = NULL; 502 frontend_ = NULL;
516 503
517 // Stop listening for and forwarding locally-triggered sync refresh requests. 504 // Stop listening for and forwarding locally-triggered sync refresh requests.
518 notification_registrar_.RemoveAll(); 505 notification_registrar_.RemoveAll();
519 506
520 DCHECK(registrar_->sync_thread()->IsRunning()); 507 DCHECK(registrar_->sync_thread()->IsRunning());
521 508
522 registrar_->RequestWorkerStopOnUIThread(); 509 registrar_->RequestWorkerStopOnUIThread();
523 510
524 StopSyncManagerForShutdown(); 511 cancelation_signal_->RequestStop();
525 } 512 }
526 513
527 scoped_ptr<base::Thread> SyncBackendHost::Shutdown(ShutdownOption option) { 514 scoped_ptr<base::Thread> SyncBackendHost::Shutdown(ShutdownOption option) {
528 // StopSyncingForShutdown() (which nulls out |frontend_|) should be 515 // StopSyncingForShutdown() (which nulls out |frontend_|) should be
529 // called first. 516 // called first.
530 DCHECK(!frontend_); 517 DCHECK(!frontend_);
531 DCHECK(registrar_->sync_thread()->IsRunning()); 518 DCHECK(registrar_->sync_thread()->IsRunning());
532 519
533 bool sync_disabled = (option == DISABLE_AND_CLAIM_THREAD); 520 bool sync_disabled = (option == DISABLE_AND_CLAIM_THREAD);
534 bool sync_thread_claimed = 521 bool sync_thread_claimed =
535 (option == DISABLE_AND_CLAIM_THREAD || option == STOP_AND_CLAIM_THREAD); 522 (option == DISABLE_AND_CLAIM_THREAD || option == STOP_AND_CLAIM_THREAD);
536 523
537 if (invalidation_handler_registered_) { 524 if (invalidation_handler_registered_) {
538 if (sync_disabled) { 525 if (sync_disabled) {
539 UnregisterInvalidationIds(); 526 UnregisterInvalidationIds();
540 } 527 }
541 invalidator_->UnregisterInvalidationHandler(this); 528 invalidator_->UnregisterInvalidationHandler(this);
542 invalidator_ = NULL; 529 invalidator_ = NULL;
543 } 530 }
544 invalidation_handler_registered_ = false; 531 invalidation_handler_registered_ = false;
545 532
546 // Shut down and destroy sync manager. 533 // Shut down and destroy sync manager.
534 //
535 // We're about to drop our reference to the |core_|. The only thing keeping
536 // it alive will be the reference that lives inside this closure we're about
537 // to post to the sync thread. If this closure doesn't run right away, it's
538 // possible that our Core will outlive us.
539 //
540 // This is a problem for the |cancelation_signal_|, which must outlive the
541 // SyncManager, SyncScheduler, etc. It can be destroyed only after the call
542 // to DoDestroySyncManager. The SyncBackendHost might not live that long, but
543 // this closure will. We pass ownership of the |cancelation_signal_| to this
544 // closure to keep it alive.
547 registrar_->sync_thread()->message_loop()->PostTask( 545 registrar_->sync_thread()->message_loop()->PostTask(
548 FROM_HERE, 546 FROM_HERE,
549 base::Bind(&SyncBackendHost::Core::DoShutdown, 547 base::Bind(&SyncBackendHost::Core::DoShutdown,
550 core_.get(), sync_disabled)); 548 core_.get(), sync_disabled,
549 base::Passed(&cancelation_signal_)));
551 core_ = NULL; 550 core_ = NULL;
552 551
553 // Worker cleanup. 552 // Worker cleanup.
554 SyncBackendRegistrar* detached_registrar = registrar_.release(); 553 SyncBackendRegistrar* detached_registrar = registrar_.release();
555 detached_registrar->sync_thread()->message_loop()->PostTask( 554 detached_registrar->sync_thread()->message_loop()->PostTask(
556 FROM_HERE, 555 FROM_HERE,
557 base::Bind(&SyncBackendRegistrar::Shutdown, 556 base::Bind(&SyncBackendRegistrar::Shutdown,
558 base::Unretained(detached_registrar))); 557 base::Unretained(detached_registrar)));
559 558
560 js_backend_.Reset(); 559 js_backend_.Reset();
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 const syncer::SyncCredentials& credentials, 875 const syncer::SyncCredentials& credentials,
877 const std::string& invalidator_client_id, 876 const std::string& invalidator_client_id,
878 scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory, 877 scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory,
879 bool delete_sync_data_folder, 878 bool delete_sync_data_folder,
880 const std::string& restored_key_for_bootstrapping, 879 const std::string& restored_key_for_bootstrapping,
881 const std::string& restored_keystore_key_for_bootstrapping, 880 const std::string& restored_keystore_key_for_bootstrapping,
882 scoped_ptr<InternalComponentsFactory> internal_components_factory, 881 scoped_ptr<InternalComponentsFactory> internal_components_factory,
883 scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler, 882 scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
884 syncer::ReportUnrecoverableErrorFunction 883 syncer::ReportUnrecoverableErrorFunction
885 report_unrecoverable_error_function, 884 report_unrecoverable_error_function,
886 bool use_oauth2_token) 885 bool use_oauth2_token,
886 syncer::CancelationSignal* const cancelation_signal)
887 : sync_loop(sync_loop), 887 : sync_loop(sync_loop),
888 registrar(registrar), 888 registrar(registrar),
889 routing_info(routing_info), 889 routing_info(routing_info),
890 workers(workers), 890 workers(workers),
891 extensions_activity(extensions_activity), 891 extensions_activity(extensions_activity),
892 event_handler(event_handler), 892 event_handler(event_handler),
893 service_url(service_url), 893 service_url(service_url),
894 make_http_bridge_factory_fn(make_http_bridge_factory_fn), 894 make_http_bridge_factory_fn(make_http_bridge_factory_fn),
895 credentials(credentials), 895 credentials(credentials),
896 invalidator_client_id(invalidator_client_id), 896 invalidator_client_id(invalidator_client_id),
897 sync_manager_factory(sync_manager_factory.Pass()), 897 sync_manager_factory(sync_manager_factory.Pass()),
898 delete_sync_data_folder(delete_sync_data_folder), 898 delete_sync_data_folder(delete_sync_data_folder),
899 restored_key_for_bootstrapping(restored_key_for_bootstrapping), 899 restored_key_for_bootstrapping(restored_key_for_bootstrapping),
900 restored_keystore_key_for_bootstrapping( 900 restored_keystore_key_for_bootstrapping(
901 restored_keystore_key_for_bootstrapping), 901 restored_keystore_key_for_bootstrapping),
902 internal_components_factory(internal_components_factory.Pass()), 902 internal_components_factory(internal_components_factory.Pass()),
903 unrecoverable_error_handler(unrecoverable_error_handler.Pass()), 903 unrecoverable_error_handler(unrecoverable_error_handler.Pass()),
904 report_unrecoverable_error_function( 904 report_unrecoverable_error_function(
905 report_unrecoverable_error_function), 905 report_unrecoverable_error_function),
906 use_oauth2_token(use_oauth2_token) { 906 use_oauth2_token(use_oauth2_token),
907 cancelation_signal(cancelation_signal) {
907 } 908 }
908 909
909 SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {} 910 SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {}
910 911
911 SyncBackendHost::Core::Core(const std::string& name, 912 SyncBackendHost::Core::Core(const std::string& name,
912 const base::FilePath& sync_data_folder_path, 913 const base::FilePath& sync_data_folder_path,
913 const base::WeakPtr<SyncBackendHost>& backend) 914 const base::WeakPtr<SyncBackendHost>& backend)
914 : name_(name), 915 : name_(name),
915 sync_data_folder_path_(sync_data_folder_path), 916 sync_data_folder_path_(sync_data_folder_path),
916 host_(backend), 917 host_(backend),
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 options->extensions_activity, 1162 options->extensions_activity,
1162 options->registrar /* as SyncManager::ChangeDelegate */, 1163 options->registrar /* as SyncManager::ChangeDelegate */,
1163 options->credentials, 1164 options->credentials,
1164 options->invalidator_client_id, 1165 options->invalidator_client_id,
1165 options->restored_key_for_bootstrapping, 1166 options->restored_key_for_bootstrapping,
1166 options->restored_keystore_key_for_bootstrapping, 1167 options->restored_keystore_key_for_bootstrapping,
1167 options->internal_components_factory.get(), 1168 options->internal_components_factory.get(),
1168 &encryptor_, 1169 &encryptor_,
1169 options->unrecoverable_error_handler.Pass(), 1170 options->unrecoverable_error_handler.Pass(),
1170 options->report_unrecoverable_error_function, 1171 options->report_unrecoverable_error_function,
1171 options->use_oauth2_token); 1172 options->use_oauth2_token,
1173 options->cancelation_signal);
1172 1174
1173 // |sync_manager_| may end up being NULL here in tests (in 1175 // |sync_manager_| may end up being NULL here in tests (in
1174 // synchronous initialization mode). 1176 // synchronous initialization mode).
1175 // 1177 //
1176 // TODO(akalin): Fix this behavior (see http://crbug.com/140354). 1178 // TODO(akalin): Fix this behavior (see http://crbug.com/140354).
1177 if (sync_manager_) { 1179 if (sync_manager_) {
1178 // Now check the command line to see if we need to simulate an 1180 // Now check the command line to see if we need to simulate an
1179 // unrecoverable error for testing purpose. Note the error is thrown 1181 // unrecoverable error for testing purpose. Note the error is thrown
1180 // only if the initialization succeeded. Also it makes sense to use this 1182 // only if the initialization succeeded. Also it makes sense to use this
1181 // flag only when restarting the browser with an account already setup. If 1183 // flag only when restarting the browser with an account already setup. If
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 DCHECK_EQ(base::MessageLoop::current(), sync_loop_); 1273 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
1272 sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase( 1274 sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase(
1273 passphrase); 1275 passphrase);
1274 } 1276 }
1275 1277
1276 void SyncBackendHost::Core::DoEnableEncryptEverything() { 1278 void SyncBackendHost::Core::DoEnableEncryptEverything() {
1277 DCHECK_EQ(base::MessageLoop::current(), sync_loop_); 1279 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
1278 sync_manager_->GetEncryptionHandler()->EnableEncryptEverything(); 1280 sync_manager_->GetEncryptionHandler()->EnableEncryptEverything();
1279 } 1281 }
1280 1282
1281 void SyncBackendHost::Core::DoStopSyncManagerForShutdown() { 1283 void SyncBackendHost::Core::DoShutdown(
1282 if (sync_manager_) 1284 bool sync_disabled,
1283 sync_manager_->StopSyncingForShutdown(); 1285 scoped_ptr<syncer::CancelationSignal> signal) {
1284 } 1286 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
1285 1287
1286 void SyncBackendHost::Core::DoShutdown(bool sync_disabled) {
1287 DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
1288 // It's safe to do this even if the type was never activated. 1288 // It's safe to do this even if the type was never activated.
1289 registrar_->DeactivateDataType(syncer::DEVICE_INFO); 1289 registrar_->DeactivateDataType(syncer::DEVICE_INFO);
1290 synced_device_tracker_.reset(); 1290 synced_device_tracker_.reset();
1291 1291
1292 DoDestroySyncManager(); 1292 DoDestroySyncManager();
1293 1293
1294 registrar_ = NULL; 1294 registrar_ = NULL;
1295 1295
1296 if (sync_disabled) 1296 if (sync_disabled)
1297 DeleteSyncDataFolder(); 1297 DeleteSyncDataFolder();
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 1605
1606 base::MessageLoop* SyncBackendHost::GetSyncLoopForTesting() { 1606 base::MessageLoop* SyncBackendHost::GetSyncLoopForTesting() {
1607 return registrar_->sync_thread()->message_loop(); 1607 return registrar_->sync_thread()->message_loop();
1608 } 1608 }
1609 1609
1610 #undef SDVLOG 1610 #undef SDVLOG
1611 1611
1612 #undef SLOG 1612 #undef SLOG
1613 1613
1614 } // namespace browser_sync 1614 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/sync_backend_host.h ('k') | sync/engine/net/server_connection_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698