| Index: chrome/browser/sync/glue/generic_change_processor.cc
|
| diff --git a/chrome/browser/sync/glue/generic_change_processor.cc b/chrome/browser/sync/glue/generic_change_processor.cc
|
| index 8a064af20c4d499b27e6799e7d027245416e36b0..eb8e4b45bba969b8e46d68ab387ae37d853a17cb 100644
|
| --- a/chrome/browser/sync/glue/generic_change_processor.cc
|
| +++ b/chrome/browser/sync/glue/generic_change_processor.cc
|
| @@ -17,21 +17,45 @@
|
| #include "chrome/browser/sync/internal_api/write_transaction.h"
|
| #include "chrome/browser/sync/unrecoverable_error_handler.h"
|
|
|
| +using base::AutoLock;
|
| +
|
| namespace browser_sync {
|
|
|
| GenericChangeProcessor::GenericChangeProcessor(
|
| - SyncableService* local_service,
|
| + UnrecoverableErrorHandler* error_handler)
|
| + : ChangeProcessor(error_handler),
|
| + local_service_(NULL),
|
| + user_share_(NULL),
|
| + disconnected_(false) {}
|
| +
|
| +GenericChangeProcessor::GenericChangeProcessor(
|
| UnrecoverableErrorHandler* error_handler,
|
| + SyncableService* local_service,
|
| sync_api::UserShare* user_share)
|
| : ChangeProcessor(error_handler),
|
| - local_service_(local_service),
|
| - user_share_(user_share) {
|
| - DCHECK(local_service_);
|
| + local_service_(NULL),
|
| + user_share_(NULL),
|
| + disconnected_(false) {
|
| + Connect(local_service, user_share);
|
| +}
|
| +
|
| +GenericChangeProcessor::~GenericChangeProcessor() {}
|
| +
|
| +// Connect to the syncer and SyncableService specified.
|
| +void GenericChangeProcessor::Connect(SyncableService* local_service,
|
| + sync_api::UserShare* user_share) {
|
| + AutoLock lock(monitor_lock_);
|
| + if (disconnected_)
|
| + return;
|
| + DCHECK(local_service);
|
| + local_service_ = local_service;
|
| + user_share_ = user_share;
|
| }
|
|
|
| -GenericChangeProcessor::~GenericChangeProcessor() {
|
| - // Set to null to ensure it's not used after destruction.
|
| - local_service_ = NULL;
|
| +void GenericChangeProcessor::Disconnect() {
|
| + VLOG(1) << "Disconnecting change processor.";
|
| + AutoLock lock(monitor_lock_);
|
| + disconnected_ = true;
|
| }
|
|
|
| void GenericChangeProcessor::ApplyChangesFromSyncModel(
|
| @@ -70,7 +94,7 @@ void GenericChangeProcessor::CommitChangesFromSyncModel() {
|
| if (syncer_changes_.empty())
|
| return;
|
| SyncError error = local_service_->ProcessSyncChanges(FROM_HERE,
|
| - syncer_changes_);
|
| + syncer_changes_);
|
| syncer_changes_.clear();
|
| if (error.IsSet()) {
|
| error_handler()->OnUnrecoverableError(error.location(), error.message());
|
| @@ -80,6 +104,11 @@ void GenericChangeProcessor::CommitChangesFromSyncModel() {
|
| SyncError GenericChangeProcessor::GetSyncDataForType(
|
| syncable::ModelType type,
|
| SyncDataList* current_sync_data) {
|
| + AutoLock lock(monitor_lock_);
|
| + if (disconnected_) {
|
| + SyncError error(FROM_HERE, "Change processor disconnected.", type);
|
| + return error;
|
| + }
|
| std::string type_name = syncable::ModelTypeToString(type);
|
| sync_api::ReadTransaction trans(FROM_HERE, share_handle());
|
| sync_api::ReadNode root(&trans);
|
| @@ -137,6 +166,17 @@ bool AttemptDelete(const SyncChange& change, sync_api::WriteNode* node) {
|
| SyncError GenericChangeProcessor::ProcessSyncChanges(
|
| const tracked_objects::Location& from_here,
|
| const SyncChangeList& list_of_changes) {
|
| + AutoLock lock(monitor_lock_);
|
| + if (disconnected_) {
|
| + syncable::ModelType type;
|
| + if (list_of_changes.size() > 0) {
|
| + type = list_of_changes[0].sync_data().GetDataType();
|
| + local_service_->StopSyncing(type);
|
| + }
|
| + SyncError error(FROM_HERE, "Change processor disconnected.",
|
| + syncable::UNSPECIFIED);
|
| + return error;
|
| + }
|
| sync_api::WriteTransaction trans(from_here, share_handle());
|
|
|
| for (SyncChangeList::const_iterator iter = list_of_changes.begin();
|
| @@ -216,6 +256,11 @@ SyncError GenericChangeProcessor::ProcessSyncChanges(
|
| bool GenericChangeProcessor::SyncModelHasUserCreatedNodes(
|
| syncable::ModelType type,
|
| bool* has_nodes) {
|
| + AutoLock lock(monitor_lock_);
|
| + if (disconnected_) {
|
| + LOG(ERROR) << "Change processor disconnected.";
|
| + return false;
|
| + }
|
| DCHECK(has_nodes);
|
| DCHECK_NE(type, syncable::UNSPECIFIED);
|
| std::string type_name = syncable::ModelTypeToString(type);
|
| @@ -236,6 +281,11 @@ bool GenericChangeProcessor::SyncModelHasUserCreatedNodes(
|
| }
|
|
|
| bool GenericChangeProcessor::CryptoReadyIfNecessary(syncable::ModelType type) {
|
| + AutoLock lock(monitor_lock_);
|
| + if (disconnected_) {
|
| + LOG(ERROR) << "Change processor disconnected.";
|
| + return true; // Otherwise we get into infinite spin waiting.
|
| + }
|
| DCHECK_NE(type, syncable::UNSPECIFIED);
|
| // We only access the cryptographer while holding a transaction.
|
| sync_api::ReadTransaction trans(FROM_HERE, share_handle());
|
| @@ -247,7 +297,9 @@ bool GenericChangeProcessor::CryptoReadyIfNecessary(syncable::ModelType type) {
|
|
|
| void GenericChangeProcessor::StartImpl(Profile* profile) {}
|
|
|
| -void GenericChangeProcessor::StopImpl() {}
|
| +void GenericChangeProcessor::StopImpl() {
|
| + Disconnect();
|
| +}
|
|
|
| sync_api::UserShare* GenericChangeProcessor::share_handle() {
|
| return user_share_;
|
|
|