Index: chrome/browser/sync/glue/non_frontend_data_type_controller.cc |
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc |
index 75b33328eb13fbeddfae76dfa15158f6c7a8b4fa..f4468843ac16dd48e845e770bc24b7a2da692912 100644 |
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc |
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc |
@@ -4,6 +4,8 @@ |
#include "chrome/browser/sync/glue/non_frontend_data_type_controller.h" |
+#include "base/bind.h" |
+#include "base/callback.h" |
#include "base/logging.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/sync/api/sync_error.h" |
@@ -60,8 +62,7 @@ void NonFrontendDataTypeController::Start(StartCallback* start_callback) { |
state_ = MODEL_STARTING; |
if (!StartModels()) { |
// If we are waiting for some external service to load before associating |
- // or we failed to start the models, we exit early. state_ will control |
- // what we perform next. |
+ // or we failed to start the models, we exit early. |
DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); |
return; |
} |
@@ -116,7 +117,7 @@ void NonFrontendDataTypeController::StartAssociation() { |
} |
profile_sync_service_->ActivateDataType(type(), model_safe_group(), |
- change_processor_.get()); |
+ change_processor()); |
StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, RUNNING, SyncError()); |
} |
@@ -139,12 +140,11 @@ void NonFrontendDataTypeController::StartDone( |
base::AutoLock lock(abort_association_lock_); |
if (!abort_association_) { |
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
- NewRunnableMethod( |
- this, |
- &NonFrontendDataTypeController::StartDoneImpl, |
- result, |
- new_state, |
- error)); |
+ base::Bind(&NonFrontendDataTypeController::StartDoneImpl, |
+ this, |
+ result, |
+ new_state, |
+ error)); |
} |
} |
@@ -153,13 +153,14 @@ void NonFrontendDataTypeController::StartDoneImpl( |
DataTypeController::State new_state, |
const SyncError& error) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
+ // It's possible to have StartDoneImpl called first from the UI thread |
+ // (due to Stop being called) and then posted from the non-UI thread. In |
+ // this case, we drop the second call because we've already been stopped. |
if (state_ == NOT_RUNNING) { |
- // During stop it is possible startdoneimpl can be called twice. Once from |
- // the |StartDone| method and once from the |Stop| method. |
DCHECK(!start_callback_.get()); |
return; |
} |
+ |
state_ = new_state; |
if (state_ != RUNNING) { |
// Start failed. |
@@ -174,9 +175,9 @@ void NonFrontendDataTypeController::StartDoneImpl( |
callback->Run(result, error); |
} |
-// TODO(sync): Blocking the UI thread at shutdown is bad. If we had a way of |
-// distinguishing chrome shutdown from sync shutdown, we should be able to avoid |
-// this (http://crbug.com/55662). |
+// TODO(sync): Blocking the UI thread at shutdown is bad. The new API avoids |
+// this. Once all non-frontend datatypes use the new API, we can get rid of this |
+// locking (see implementation in AutofillProfileDataTypeController). |
void NonFrontendDataTypeController::Stop() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
// If Stop() is called while Start() is waiting for association to |
@@ -253,9 +254,11 @@ void NonFrontendDataTypeController::OnUnrecoverableError( |
const std::string& message) { |
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
RecordUnrecoverableError(from_here, message); |
- BrowserThread::PostTask(BrowserThread::UI, from_here, NewRunnableMethod(this, |
- &NonFrontendDataTypeController::OnUnrecoverableErrorImpl, from_here, |
- message)); |
+ BrowserThread::PostTask(BrowserThread::UI, from_here, |
+ base::Bind(&NonFrontendDataTypeController::OnUnrecoverableErrorImpl, |
+ this, |
+ from_here, |
+ message)); |
} |
void NonFrontendDataTypeController::OnUnrecoverableErrorImpl( |
@@ -279,15 +282,27 @@ ProfileSyncService* NonFrontendDataTypeController::profile_sync_service() |
return profile_sync_service_; |
} |
+void NonFrontendDataTypeController::set_start_callback( |
+ StartCallback* callback) { |
+ start_callback_.reset(callback); |
+} |
void NonFrontendDataTypeController::set_state(State state) { |
state_ = state; |
} |
+AssociatorInterface* NonFrontendDataTypeController::associator() const { |
+ return model_associator_.get(); |
+} |
+ |
void NonFrontendDataTypeController::set_model_associator( |
AssociatorInterface* associator) { |
model_associator_.reset(associator); |
} |
+ChangeProcessor* NonFrontendDataTypeController::change_processor() const { |
+ return change_processor_.get(); |
+} |
+ |
void NonFrontendDataTypeController::set_change_processor( |
ChangeProcessor* change_processor) { |
change_processor_.reset(change_processor); |