[GCM] Investigatory CHECKs for crash in parsing stream
[chromium-blink-merge.git] / components / sync_driver / shared_change_processor.cc
blobc1cf407e74647f25db86a9309fccb236b4bfeeb6
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/sync_driver/shared_change_processor.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "components/sync_driver/generic_change_processor.h"
9 #include "components/sync_driver/generic_change_processor_factory.h"
10 #include "components/sync_driver/sync_api_component_factory.h"
11 #include "sync/api/sync_change.h"
13 using base::AutoLock;
15 namespace sync_driver {
17 SharedChangeProcessor::SharedChangeProcessor()
18 : disconnected_(false),
19 type_(syncer::UNSPECIFIED),
20 frontend_loop_(base::MessageLoopProxy::current()),
21 generic_change_processor_(NULL),
22 error_handler_(NULL) {
25 SharedChangeProcessor::~SharedChangeProcessor() {
26 // We can either be deleted when the DTC is destroyed (on UI
27 // thread), or when the syncer::SyncableService stop's syncing (datatype
28 // thread). |generic_change_processor_|, if non-NULL, must be
29 // deleted on |backend_loop_|.
30 if (frontend_loop_->BelongsToCurrentThread()) {
31 if (backend_loop_.get()) {
32 if (!backend_loop_->DeleteSoon(FROM_HERE, generic_change_processor_)) {
33 NOTREACHED();
35 } else {
36 DCHECK(!generic_change_processor_);
38 } else {
39 DCHECK(backend_loop_.get());
40 DCHECK(backend_loop_->BelongsToCurrentThread());
41 delete generic_change_processor_;
45 base::WeakPtr<syncer::SyncableService> SharedChangeProcessor::Connect(
46 SyncApiComponentFactory* sync_factory,
47 GenericChangeProcessorFactory* processor_factory,
48 syncer::UserShare* user_share,
49 DataTypeErrorHandler* error_handler,
50 syncer::ModelType type,
51 const base::WeakPtr<syncer::SyncMergeResult>& merge_result) {
52 DCHECK(sync_factory);
53 DCHECK(error_handler);
54 DCHECK_NE(type, syncer::UNSPECIFIED);
55 backend_loop_ = base::MessageLoopProxy::current();
56 AutoLock lock(monitor_lock_);
57 if (disconnected_)
58 return base::WeakPtr<syncer::SyncableService>();
59 type_ = type;
60 error_handler_ = error_handler;
61 base::WeakPtr<syncer::SyncableService> local_service =
62 sync_factory->GetSyncableServiceForType(type);
63 if (!local_service.get()) {
64 LOG(WARNING) << "SyncableService destroyed before DTC was stopped.";
65 disconnected_ = true;
66 return base::WeakPtr<syncer::SyncableService>();
69 generic_change_processor_ =
70 processor_factory->CreateGenericChangeProcessor(type,
71 user_share,
72 error_handler,
73 local_service,
74 merge_result,
75 sync_factory).release();
76 return local_service;
79 bool SharedChangeProcessor::Disconnect() {
80 // May be called from any thread.
81 DVLOG(1) << "Disconnecting change processor.";
82 AutoLock lock(monitor_lock_);
83 bool was_connected = !disconnected_;
84 disconnected_ = true;
85 error_handler_ = NULL;
86 return was_connected;
89 ChangeProcessor* SharedChangeProcessor::generic_change_processor() {
90 return generic_change_processor_;
93 int SharedChangeProcessor::GetSyncCount() {
94 DCHECK(backend_loop_.get());
95 DCHECK(backend_loop_->BelongsToCurrentThread());
96 AutoLock lock(monitor_lock_);
97 if (disconnected_) {
98 LOG(ERROR) << "Change processor disconnected.";
99 return 0;
101 return generic_change_processor_->GetSyncCount();
104 syncer::SyncError SharedChangeProcessor::ProcessSyncChanges(
105 const tracked_objects::Location& from_here,
106 const syncer::SyncChangeList& list_of_changes) {
107 DCHECK(backend_loop_.get());
108 DCHECK(backend_loop_->BelongsToCurrentThread());
109 AutoLock lock(monitor_lock_);
110 if (disconnected_) {
111 // The DTC that disconnects us must ensure it posts a StopSyncing task.
112 // If we reach this, it means it just hasn't executed yet.
113 syncer::SyncError error(FROM_HERE,
114 syncer::SyncError::DATATYPE_ERROR,
115 "Change processor disconnected.",
116 type_);
117 return error;
119 return generic_change_processor_->ProcessSyncChanges(
120 from_here, list_of_changes);
123 syncer::SyncDataList SharedChangeProcessor::GetAllSyncData(
124 syncer::ModelType type) const {
125 syncer::SyncDataList data;
126 GetAllSyncDataReturnError(type, &data); // Handles the disconnect case.
127 return data;
130 syncer::SyncError SharedChangeProcessor::GetAllSyncDataReturnError(
131 syncer::ModelType type,
132 syncer::SyncDataList* data) const {
133 DCHECK(backend_loop_.get());
134 DCHECK(backend_loop_->BelongsToCurrentThread());
135 AutoLock lock(monitor_lock_);
136 if (disconnected_) {
137 syncer::SyncError error(FROM_HERE,
138 syncer::SyncError::DATATYPE_ERROR,
139 "Change processor disconnected.",
140 type_);
141 return error;
143 return generic_change_processor_->GetAllSyncDataReturnError(data);
146 syncer::SyncError SharedChangeProcessor::UpdateDataTypeContext(
147 syncer::ModelType type,
148 syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status,
149 const std::string& context) {
150 DCHECK(backend_loop_.get());
151 DCHECK(backend_loop_->BelongsToCurrentThread());
152 AutoLock lock(monitor_lock_);
153 if (disconnected_) {
154 syncer::SyncError error(FROM_HERE,
155 syncer::SyncError::DATATYPE_ERROR,
156 "Change processor disconnected.",
157 type_);
158 return error;
160 return generic_change_processor_->UpdateDataTypeContext(
161 type, refresh_status, context);
164 bool SharedChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) {
165 DCHECK(backend_loop_.get());
166 DCHECK(backend_loop_->BelongsToCurrentThread());
167 AutoLock lock(monitor_lock_);
168 if (disconnected_) {
169 LOG(ERROR) << "Change processor disconnected.";
170 return false;
172 return generic_change_processor_->SyncModelHasUserCreatedNodes(has_nodes);
175 bool SharedChangeProcessor::CryptoReadyIfNecessary() {
176 DCHECK(backend_loop_.get());
177 DCHECK(backend_loop_->BelongsToCurrentThread());
178 AutoLock lock(monitor_lock_);
179 if (disconnected_) {
180 LOG(ERROR) << "Change processor disconnected.";
181 return true; // Otherwise we get into infinite spin waiting.
183 return generic_change_processor_->CryptoReadyIfNecessary();
186 bool SharedChangeProcessor::GetDataTypeContext(std::string* context) const {
187 DCHECK(backend_loop_.get());
188 DCHECK(backend_loop_->BelongsToCurrentThread());
189 AutoLock lock(monitor_lock_);
190 if (disconnected_) {
191 LOG(ERROR) << "Change processor disconnected.";
192 return false;
194 return generic_change_processor_->GetDataTypeContext(context);
197 syncer::SyncError SharedChangeProcessor::CreateAndUploadError(
198 const tracked_objects::Location& location,
199 const std::string& message) {
200 AutoLock lock(monitor_lock_);
201 if (!disconnected_) {
202 return error_handler_->CreateAndUploadError(location, message, type_);
203 } else {
204 return syncer::SyncError(location,
205 syncer::SyncError::DATATYPE_ERROR,
206 message,
207 type_);
211 } // namespace sync_driver