OLD | NEW |
1 // Copyright (c) 2011 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/shared_change_processor.h" | 5 #include "chrome/browser/sync/glue/shared_change_processor.h" |
6 | 6 |
7 #include "chrome/browser/sync/api/sync_change.h" | 7 #include "chrome/browser/sync/api/sync_change.h" |
8 #include "chrome/browser/sync/glue/generic_change_processor.h" | 8 #include "chrome/browser/sync/glue/generic_change_processor.h" |
9 #include "chrome/browser/sync/profile_sync_components_factory.h" | 9 #include "chrome/browser/sync/profile_sync_components_factory.h" |
10 #include "chrome/browser/sync/profile_sync_service.h" | 10 #include "chrome/browser/sync/profile_sync_service.h" |
11 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
12 | 12 |
13 using base::AutoLock; | 13 using base::AutoLock; |
14 using content::BrowserThread; | 14 using content::BrowserThread; |
15 | 15 |
16 namespace browser_sync { | 16 namespace browser_sync { |
17 | 17 |
18 SharedChangeProcessor::SharedChangeProcessor() | 18 SharedChangeProcessor::SharedChangeProcessor() |
19 : disconnected_(false) { | 19 : disconnected_(false), |
| 20 generic_change_processor_(NULL) { |
20 // We're always created on the UI thread. | 21 // We're always created on the UI thread. |
21 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 22 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
22 DetachFromThread(); | |
23 } | 23 } |
24 | 24 |
25 SharedChangeProcessor::~SharedChangeProcessor() { | 25 SharedChangeProcessor::~SharedChangeProcessor() { |
26 // We can either be deleted when the DTC is destroyed (on UI thread), | 26 // We can either be deleted when the DTC is destroyed (on UI |
27 // or when the SyncableService stop's syncing (datatype thread). | 27 // thread), or when the SyncableService stop's syncing (datatype |
28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 28 // thread). |generic_change_processor_|, if non-NULL, must be |
29 CalledOnValidThread()); | 29 // deleted on |backend_loop_|. |
30 DetachFromThread(); | 30 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| 31 if (backend_loop_.get()) { |
| 32 backend_loop_->DeleteSoon(FROM_HERE, generic_change_processor_); |
| 33 } else { |
| 34 DCHECK(!generic_change_processor_); |
| 35 } |
| 36 } else { |
| 37 DCHECK(backend_loop_.get()); |
| 38 DCHECK(backend_loop_->BelongsToCurrentThread()); |
| 39 delete generic_change_processor_; |
| 40 } |
31 } | 41 } |
32 | 42 |
33 bool SharedChangeProcessor::Connect( | 43 bool SharedChangeProcessor::Connect( |
34 ProfileSyncComponentsFactory* sync_factory, | 44 ProfileSyncComponentsFactory* sync_factory, |
35 ProfileSyncService* sync_service, | 45 ProfileSyncService* sync_service, |
36 UnrecoverableErrorHandler* error_handler, | 46 UnrecoverableErrorHandler* error_handler, |
37 const base::WeakPtr<SyncableService>& local_service) { | 47 const base::WeakPtr<SyncableService>& local_service) { |
38 DCHECK(CalledOnValidThread()); | 48 backend_loop_ = base::MessageLoopProxy::current(); |
39 AutoLock lock(monitor_lock_); | 49 AutoLock lock(monitor_lock_); |
40 if (disconnected_) | 50 if (disconnected_) |
41 return false; | 51 return false; |
42 if (!local_service) { | 52 if (!local_service) { |
43 NOTREACHED() << "SyncableService destroyed before DTC was stopped."; | 53 NOTREACHED() << "SyncableService destroyed before DTC was stopped."; |
44 disconnected_ = true; | 54 disconnected_ = true; |
45 return false; | 55 return false; |
46 } | 56 } |
47 generic_change_processor_.reset( | 57 generic_change_processor_ = |
48 sync_factory->CreateGenericChangeProcessor(sync_service, | 58 sync_factory->CreateGenericChangeProcessor(sync_service, |
49 error_handler, | 59 error_handler, |
50 local_service)); | 60 local_service); |
51 return true; | 61 return true; |
52 } | 62 } |
53 | 63 |
54 bool SharedChangeProcessor::Disconnect() { | 64 bool SharedChangeProcessor::Disconnect() { |
55 // May be called from any thread. | 65 // May be called from any thread. |
56 DVLOG(1) << "Disconnecting change processor."; | 66 DVLOG(1) << "Disconnecting change processor."; |
57 AutoLock lock(monitor_lock_); | 67 AutoLock lock(monitor_lock_); |
58 bool was_connected = !disconnected_; | 68 bool was_connected = !disconnected_; |
59 disconnected_ = true; | 69 disconnected_ = true; |
60 return was_connected; | 70 return was_connected; |
61 } | 71 } |
62 | 72 |
63 SyncError SharedChangeProcessor::GetSyncDataForType( | 73 SyncError SharedChangeProcessor::GetSyncDataForType( |
64 syncable::ModelType type, | 74 syncable::ModelType type, |
65 SyncDataList* current_sync_data) { | 75 SyncDataList* current_sync_data) { |
66 DCHECK(CalledOnValidThread()); | 76 DCHECK(backend_loop_.get()); |
| 77 DCHECK(backend_loop_->BelongsToCurrentThread()); |
67 AutoLock lock(monitor_lock_); | 78 AutoLock lock(monitor_lock_); |
68 if (disconnected_) { | 79 if (disconnected_) { |
69 SyncError error(FROM_HERE, "Change processor disconnected.", type); | 80 SyncError error(FROM_HERE, "Change processor disconnected.", type); |
70 return error; | 81 return error; |
71 } | 82 } |
72 return generic_change_processor_->GetSyncDataForType(type, current_sync_data); | 83 return generic_change_processor_->GetSyncDataForType(type, current_sync_data); |
73 } | 84 } |
74 | 85 |
75 SyncError SharedChangeProcessor::ProcessSyncChanges( | 86 SyncError SharedChangeProcessor::ProcessSyncChanges( |
76 const tracked_objects::Location& from_here, | 87 const tracked_objects::Location& from_here, |
77 const SyncChangeList& list_of_changes) { | 88 const SyncChangeList& list_of_changes) { |
78 DCHECK(CalledOnValidThread()); | 89 DCHECK(backend_loop_.get()); |
| 90 DCHECK(backend_loop_->BelongsToCurrentThread()); |
79 AutoLock lock(monitor_lock_); | 91 AutoLock lock(monitor_lock_); |
80 if (disconnected_) { | 92 if (disconnected_) { |
81 // The DTC that disconnects us must ensure it posts a StopSyncing task. | 93 // The DTC that disconnects us must ensure it posts a StopSyncing task. |
82 // If we reach this, it means it just hasn't executed yet. | 94 // If we reach this, it means it just hasn't executed yet. |
83 syncable::ModelType type = syncable::UNSPECIFIED; | 95 syncable::ModelType type = syncable::UNSPECIFIED; |
84 if (list_of_changes.size() > 0) { | 96 if (list_of_changes.size() > 0) { |
85 type = list_of_changes[0].sync_data().GetDataType(); | 97 type = list_of_changes[0].sync_data().GetDataType(); |
86 } | 98 } |
87 SyncError error(FROM_HERE, "Change processor disconnected.", type); | 99 SyncError error(FROM_HERE, "Change processor disconnected.", type); |
88 return error; | 100 return error; |
89 } | 101 } |
90 return generic_change_processor_->ProcessSyncChanges( | 102 return generic_change_processor_->ProcessSyncChanges( |
91 from_here, list_of_changes); | 103 from_here, list_of_changes); |
92 } | 104 } |
93 | 105 |
94 bool SharedChangeProcessor::SyncModelHasUserCreatedNodes( | 106 bool SharedChangeProcessor::SyncModelHasUserCreatedNodes( |
95 syncable::ModelType type, | 107 syncable::ModelType type, |
96 bool* has_nodes) { | 108 bool* has_nodes) { |
97 DCHECK(CalledOnValidThread()); | 109 DCHECK(backend_loop_.get()); |
| 110 DCHECK(backend_loop_->BelongsToCurrentThread()); |
98 AutoLock lock(monitor_lock_); | 111 AutoLock lock(monitor_lock_); |
99 if (disconnected_) { | 112 if (disconnected_) { |
100 LOG(ERROR) << "Change processor disconnected."; | 113 LOG(ERROR) << "Change processor disconnected."; |
101 return false; | 114 return false; |
102 } | 115 } |
103 return generic_change_processor_->SyncModelHasUserCreatedNodes( | 116 return generic_change_processor_->SyncModelHasUserCreatedNodes( |
104 type, has_nodes); | 117 type, has_nodes); |
105 } | 118 } |
106 | 119 |
107 bool SharedChangeProcessor::CryptoReadyIfNecessary(syncable::ModelType type) { | 120 bool SharedChangeProcessor::CryptoReadyIfNecessary(syncable::ModelType type) { |
108 DCHECK(CalledOnValidThread()); | 121 DCHECK(backend_loop_.get()); |
| 122 DCHECK(backend_loop_->BelongsToCurrentThread()); |
109 AutoLock lock(monitor_lock_); | 123 AutoLock lock(monitor_lock_); |
110 if (disconnected_) { | 124 if (disconnected_) { |
111 LOG(ERROR) << "Change processor disconnected."; | 125 LOG(ERROR) << "Change processor disconnected."; |
112 return true; // Otherwise we get into infinite spin waiting. | 126 return true; // Otherwise we get into infinite spin waiting. |
113 } | 127 } |
114 return generic_change_processor_->CryptoReadyIfNecessary(type); | 128 return generic_change_processor_->CryptoReadyIfNecessary(type); |
115 } | 129 } |
116 | 130 |
117 void SharedChangeProcessor::ActivateDataType( | 131 void SharedChangeProcessor::ActivateDataType( |
118 ProfileSyncService* sync_service, | 132 ProfileSyncService* sync_service, |
119 syncable::ModelType model_type, | 133 syncable::ModelType model_type, |
120 browser_sync::ModelSafeGroup model_safe_group) { | 134 browser_sync::ModelSafeGroup model_safe_group) { |
| 135 DCHECK(backend_loop_.get()); |
| 136 DCHECK(backend_loop_->BelongsToCurrentThread()); |
121 AutoLock lock(monitor_lock_); | 137 AutoLock lock(monitor_lock_); |
122 if (disconnected_) { | 138 if (disconnected_) { |
123 LOG(ERROR) << "Change processor disconnected."; | 139 LOG(ERROR) << "Change processor disconnected."; |
124 return; | 140 return; |
125 } | 141 } |
126 sync_service->ActivateDataType( | 142 sync_service->ActivateDataType( |
127 model_type, model_safe_group, generic_change_processor_.get()); | 143 model_type, model_safe_group, generic_change_processor_); |
128 } | 144 } |
129 | 145 |
130 } // namespace browser_sync | 146 } // namespace browser_sync |
OLD | NEW |