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

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

Issue 10808040: [Sync] Avoid ObserverListThreadSafe in ChromeSyncNotificationBridge (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix test errors Created 8 years, 5 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) 2012 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/chrome_sync_notification_bridge.h" 5 #include "chrome/browser/sync/glue/chrome_sync_notification_bridge.h"
6 6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/observer_list.h"
7 #include "chrome/common/chrome_notification_types.h" 10 #include "chrome/common/chrome_notification_types.h"
8 #include "content/public/browser/browser_thread.h" 11 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/notification_service.h" 12 #include "content/public/browser/notification_service.h"
10 #include "sync/notifier/sync_notifier_observer.h" 13 #include "sync/notifier/sync_notifier_observer.h"
11 14
12 using content::BrowserThread; 15 using content::BrowserThread;
13 16
14 namespace browser_sync { 17 namespace browser_sync {
15 18
19 class ChromeSyncNotificationBridge::Core
20 : public base::RefCountedThreadSafe<Core> {
21 public:
22 // Created on UI thread.
23 explicit Core(
24 const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner);
25
26 // All member functions below must be called on the sync task runner.
27
28 void AddObserver(syncer::SyncNotifierObserver* observer);
29 void RemoveObserver(syncer::SyncNotifierObserver* observer);
30
31 void EmitNotification(
32 syncer::ModelTypePayloadMap payload_map,
33 syncer::IncomingNotificationSource notification_source);
34
35 private:
36 friend class base::RefCountedThreadSafe<Core>;
37
38 // Destroyed on the UI thread or on |sync_task_runner_|.
39 ~Core();
40
41 const scoped_refptr<base::SequencedTaskRunner> sync_task_runner_;
42
43 // Used only on |sync_task_runner_|.
44 syncer::ModelTypeSet enabled_types_;
45 ObserverList<syncer::SyncNotifierObserver> observers_;
46 };
47
48 ChromeSyncNotificationBridge::Core::Core(
49 const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner)
50 : sync_task_runner_(sync_task_runner) {
51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
52 DCHECK(sync_task_runner_.get());
53 }
54
55 ChromeSyncNotificationBridge::Core::~Core() {
56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
57 sync_task_runner_->RunsTasksOnCurrentThread());
58 }
59
60 void ChromeSyncNotificationBridge::Core::AddObserver(
61 syncer::SyncNotifierObserver* observer) {
62 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
63 observers_.AddObserver(observer);
64 }
65
66 void ChromeSyncNotificationBridge::Core::RemoveObserver(
67 syncer::SyncNotifierObserver* observer) {
68 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
69 observers_.RemoveObserver(observer);
70 }
71
72 void ChromeSyncNotificationBridge::Core::EmitNotification(
73 syncer::ModelTypePayloadMap payload_map,
74 syncer::IncomingNotificationSource notification_source) {
75 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
76 FOR_EACH_OBSERVER(
77 syncer::SyncNotifierObserver, observers_,
78 OnIncomingNotification(payload_map, notification_source));
79 }
80
16 ChromeSyncNotificationBridge::ChromeSyncNotificationBridge( 81 ChromeSyncNotificationBridge::ChromeSyncNotificationBridge(
17 const Profile* profile) 82 const Profile* profile,
18 : observers_( 83 const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner)
19 new ObserverListThreadSafe<syncer::SyncNotifierObserver>()) { 84 : sync_task_runner_(sync_task_runner),
85 core_(new Core(sync_task_runner_)) {
20 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
21 DCHECK(profile); 87 DCHECK(profile);
22 registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, 88 registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
23 content::Source<Profile>(profile)); 89 content::Source<Profile>(profile));
24 registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_REMOTE, 90 registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
25 content::Source<Profile>(profile)); 91 content::Source<Profile>(profile));
26 } 92 }
27 93
28 ChromeSyncNotificationBridge::~ChromeSyncNotificationBridge() {} 94 ChromeSyncNotificationBridge::~ChromeSyncNotificationBridge() {}
29 95
30 void ChromeSyncNotificationBridge::UpdateEnabledTypes( 96 void ChromeSyncNotificationBridge::UpdateEnabledTypes(
31 const syncer::ModelTypeSet types) { 97 const syncer::ModelTypeSet types) {
32 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
33 enabled_types_ = types; 99 enabled_types_ = types;
34 } 100 }
35 101
36 void ChromeSyncNotificationBridge::AddObserver( 102 void ChromeSyncNotificationBridge::AddObserver(
37 syncer::SyncNotifierObserver* observer) { 103 syncer::SyncNotifierObserver* observer) {
38 observers_->AddObserver(observer); 104 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
105 core_->AddObserver(observer);
39 } 106 }
40 107
41 void ChromeSyncNotificationBridge::RemoveObserver( 108 void ChromeSyncNotificationBridge::RemoveObserver(
42 syncer::SyncNotifierObserver* observer) { 109 syncer::SyncNotifierObserver* observer) {
43 observers_->RemoveObserver(observer); 110 DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
111 core_->RemoveObserver(observer);
44 } 112 }
45 113
46 void ChromeSyncNotificationBridge::Observe( 114 void ChromeSyncNotificationBridge::Observe(
47 int type, 115 int type,
48 const content::NotificationSource& source, 116 const content::NotificationSource& source,
49 const content::NotificationDetails& details) { 117 const content::NotificationDetails& details) {
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 119
52 syncer::IncomingNotificationSource notification_source; 120 syncer::IncomingNotificationSource notification_source;
53 if (type == chrome::NOTIFICATION_SYNC_REFRESH_LOCAL) { 121 if (type == chrome::NOTIFICATION_SYNC_REFRESH_LOCAL) {
54 notification_source = syncer::LOCAL_NOTIFICATION; 122 notification_source = syncer::LOCAL_NOTIFICATION;
55 } else if (type == chrome::NOTIFICATION_SYNC_REFRESH_REMOTE) { 123 } else if (type == chrome::NOTIFICATION_SYNC_REFRESH_REMOTE) {
56 notification_source = syncer::REMOTE_NOTIFICATION; 124 notification_source = syncer::REMOTE_NOTIFICATION;
57 } else { 125 } else {
58 NOTREACHED() << "Unexpected notification type:" << type; 126 NOTREACHED() << "Unexpected notification type: " << type;
59 return; 127 return;
60 } 128 }
61 129
62 content::Details<const syncer::ModelTypePayloadMap> 130 content::Details<const syncer::ModelTypePayloadMap>
63 payload_details(details); 131 payload_details(details);
64 syncer::ModelTypePayloadMap payload_map = *(payload_details.ptr()); 132 syncer::ModelTypePayloadMap payload_map = *(payload_details.ptr());
65 133
66 if (payload_map.empty()) { 134 if (payload_map.empty()) {
67 // No model types to invalidate, invalidating all enabled types. 135 // No model types to invalidate, invalidating all enabled types.
68 payload_map = 136 payload_map =
69 syncer::ModelTypePayloadMapFromEnumSet(enabled_types_, std::string()); 137 syncer::ModelTypePayloadMapFromEnumSet(enabled_types_, std::string());
70 } 138 }
71 139
72 observers_->Notify( 140 sync_task_runner_->PostTask(
73 &syncer::SyncNotifierObserver::OnIncomingNotification, 141 FROM_HERE,
74 payload_map, notification_source); 142 base::Bind(&Core::EmitNotification,
143 core_, payload_map, notification_source));
75 } 144 }
76 145
77 } // namespace browser_sync 146 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698