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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sync/glue/sync_backend_host.cc
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index 2f91728d69096ca2a55838b0e751a67550093421..2db700111cd3bf5afa48833edbfefbbe1911ab32 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -198,12 +198,12 @@ class SyncBackendHost::Core
void DoFinishInitialProcessControlTypes();
// The shutdown order is a bit complicated:
- // 1) Call DoStopSyncManagerForShutdown() from |frontend_loop_| to request
- // sync manager to stop as soon as possible.
+ // 1) Call the SyncManagerStopHandle's RequestStop() from |frontend_loop_| to
+ // request sync manager to stop as soon as possible.
// 2) Post DoShutdown() to sync loop to clean up backend state, save
// directory and destroy sync manager.
- void DoStopSyncManagerForShutdown();
- void DoShutdown(bool sync_disabled);
+ void DoShutdown(bool sync_disabled,
+ scoped_ptr<syncer::CancelationSignal> signal);
void DoDestroySyncManager();
// Configuration methods that must execute on sync loop.
@@ -305,7 +305,8 @@ SyncBackendHost::SyncBackendHost(
cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE),
invalidator_(
invalidation::InvalidationServiceFactory::GetForProfile(profile)),
- invalidation_handler_registered_(false) {
+ invalidation_handler_registered_(false),
+ cancelation_signal_(new syncer::CancelationSignal()) {
}
SyncBackendHost::SyncBackendHost(Profile* profile)
@@ -401,7 +402,8 @@ void SyncBackendHost::Initialize(
new InternalComponentsFactoryImpl(factory_switches)).Pass(),
unrecoverable_error_handler.Pass(),
report_unrecoverable_error_function,
- !cl->HasSwitch(switches::kSyncDisableOAuth2Token)));
+ !cl->HasSwitch(switches::kSyncDisableOAuth2Token),
+ cancelation_signal_.get()));
InitCore(init_opts.Pass());
}
@@ -492,24 +494,9 @@ bool SyncBackendHost::SetDecryptionPassphrase(const std::string& passphrase) {
return true;
}
-void SyncBackendHost::StopSyncManagerForShutdown() {
- DCHECK_GT(initialization_state_, NOT_ATTEMPTED);
- if (initialization_state_ == CREATING_SYNC_MANAGER) {
- // We post here to implicitly wait for the SyncManager to be created,
- // if needed. We have to wait, since we need to shutdown immediately,
- // and we need to tell the SyncManager so it can abort any activity
- // (net I/O, data application).
- DCHECK(registrar_->sync_thread()->IsRunning());
- registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE,
- base::Bind(&SyncBackendHost::Core::DoStopSyncManagerForShutdown,
- core_.get()));
- } else {
- core_->DoStopSyncManagerForShutdown();
- }
-}
-
void SyncBackendHost::StopSyncingForShutdown() {
DCHECK_EQ(base::MessageLoop::current(), frontend_loop_);
+ DCHECK_GT(initialization_state_, NOT_ATTEMPTED);
// Immediately stop sending messages to the frontend.
frontend_ = NULL;
@@ -521,7 +508,7 @@ void SyncBackendHost::StopSyncingForShutdown() {
registrar_->RequestWorkerStopOnUIThread();
- StopSyncManagerForShutdown();
+ cancelation_signal_->RequestStop();
}
scoped_ptr<base::Thread> SyncBackendHost::Shutdown(ShutdownOption option) {
@@ -544,10 +531,22 @@ scoped_ptr<base::Thread> SyncBackendHost::Shutdown(ShutdownOption option) {
invalidation_handler_registered_ = false;
// Shut down and destroy sync manager.
+ //
+ // We're about to drop our reference to the |core_|. The only thing keeping
+ // it alive will be the reference that lives inside this closure we're about
+ // to post to the sync thread. If this closure doesn't run right away, it's
+ // possible that our Core will outlive us.
+ //
+ // This is a problem for the |cancelation_signal_|, which must outlive the
+ // SyncManager, SyncScheduler, etc. It can be destroyed only after the call
+ // to DoDestroySyncManager. The SyncBackendHost might not live that long, but
+ // this closure will. We pass ownership of the |cancelation_signal_| to this
+ // closure to keep it alive.
registrar_->sync_thread()->message_loop()->PostTask(
FROM_HERE,
base::Bind(&SyncBackendHost::Core::DoShutdown,
- core_.get(), sync_disabled));
+ core_.get(), sync_disabled,
+ base::Passed(&cancelation_signal_)));
core_ = NULL;
// Worker cleanup.
@@ -883,7 +882,8 @@ SyncBackendHost::DoInitializeOptions::DoInitializeOptions(
scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler,
syncer::ReportUnrecoverableErrorFunction
report_unrecoverable_error_function,
- bool use_oauth2_token)
+ bool use_oauth2_token,
+ syncer::CancelationSignal* const cancelation_signal)
: sync_loop(sync_loop),
registrar(registrar),
routing_info(routing_info),
@@ -903,7 +903,8 @@ SyncBackendHost::DoInitializeOptions::DoInitializeOptions(
unrecoverable_error_handler(unrecoverable_error_handler.Pass()),
report_unrecoverable_error_function(
report_unrecoverable_error_function),
- use_oauth2_token(use_oauth2_token) {
+ use_oauth2_token(use_oauth2_token),
+ cancelation_signal(cancelation_signal) {
}
SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {}
@@ -1168,7 +1169,8 @@ void SyncBackendHost::Core::DoInitialize(
&encryptor_,
options->unrecoverable_error_handler.Pass(),
options->report_unrecoverable_error_function,
- options->use_oauth2_token);
+ options->use_oauth2_token,
+ options->cancelation_signal);
// |sync_manager_| may end up being NULL here in tests (in
// synchronous initialization mode).
@@ -1278,13 +1280,11 @@ void SyncBackendHost::Core::DoEnableEncryptEverything() {
sync_manager_->GetEncryptionHandler()->EnableEncryptEverything();
}
-void SyncBackendHost::Core::DoStopSyncManagerForShutdown() {
- if (sync_manager_)
- sync_manager_->StopSyncingForShutdown();
-}
-
-void SyncBackendHost::Core::DoShutdown(bool sync_disabled) {
+void SyncBackendHost::Core::DoShutdown(
+ bool sync_disabled,
+ scoped_ptr<syncer::CancelationSignal> signal) {
DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
+
// It's safe to do this even if the type was never activated.
registrar_->DeactivateDataType(syncer::DEVICE_INFO);
synced_device_tracker_.reset();
« 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