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

Side by Side Diff: chrome/browser/sync/glue/shared_change_processor.cc

Issue 9307079: [Sync] Fix thread-ordering-dependent NULL dereference in NewNonFrontendDTC (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync to head Created 8 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/shared_change_processor.h ('k') | chrome/browser/sync/glue/shared_change_processor_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698