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

Side by Side Diff: content/common/notification_service.cc

Issue 7327007: Moving notification types which are chrome specific to a new header file chrome_notification_type... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 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
« no previous file with comments | « content/common/notification_service.h ('k') | content/common/notification_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "content/common/notification_service.h" 5 #include "content/common/notification_service.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/threading/thread_local.h" 8 #include "base/threading/thread_local.h"
9 #include "content/common/notification_observer.h" 9 #include "content/common/notification_observer.h"
10 10
11 static base::LazyInstance<base::ThreadLocalPointer<NotificationService> > 11 static base::LazyInstance<base::ThreadLocalPointer<NotificationService> >
12 lazy_tls_ptr(base::LINKER_INITIALIZED); 12 lazy_tls_ptr(base::LINKER_INITIALIZED);
13 13
14 // static 14 // static
15 NotificationService* NotificationService::current() { 15 NotificationService* NotificationService::current() {
16 return lazy_tls_ptr.Pointer()->Get(); 16 return lazy_tls_ptr.Pointer()->Get();
17 } 17 }
18 18
19 // static 19 // static
20 bool NotificationService::HasKey(const NotificationSourceMap& map, 20 bool NotificationService::HasKey(const NotificationSourceMap& map,
21 const NotificationSource& source) { 21 const NotificationSource& source) {
22 return map.find(source.map_key()) != map.end(); 22 return map.find(source.map_key()) != map.end();
23 } 23 }
24 24
25 NotificationService::NotificationService() { 25 NotificationService::NotificationService() {
26 DCHECK(current() == NULL); 26 DCHECK(current() == NULL);
27 #ifndef NDEBUG
28 memset(observer_counts_, 0, sizeof(observer_counts_));
29 #endif
30
31 lazy_tls_ptr.Pointer()->Set(this); 27 lazy_tls_ptr.Pointer()->Set(this);
32 } 28 }
33 29
34 void NotificationService::AddObserver(NotificationObserver* observer, 30 void NotificationService::AddObserver(NotificationObserver* observer,
35 NotificationType type, 31 int type,
36 const NotificationSource& source) { 32 const NotificationSource& source) {
37 DCHECK(type.value < NotificationType::NOTIFICATION_TYPE_COUNT);
38
39 // We have gotten some crashes where the observer pointer is NULL. The problem 33 // We have gotten some crashes where the observer pointer is NULL. The problem
40 // is that this happens when we actually execute a notification, so have no 34 // is that this happens when we actually execute a notification, so have no
41 // way of knowing who the bad observer was. We want to know when this happens 35 // way of knowing who the bad observer was. We want to know when this happens
42 // in release mode so we know what code to blame the crash on (since this is 36 // in release mode so we know what code to blame the crash on (since this is
43 // guaranteed to crash later). 37 // guaranteed to crash later).
44 CHECK(observer); 38 CHECK(observer);
45 39
46 NotificationObserverList* observer_list; 40 NotificationObserverList* observer_list;
47 if (HasKey(observers_[type.value], source)) { 41 if (HasKey(observers_[type], source)) {
48 observer_list = observers_[type.value][source.map_key()]; 42 observer_list = observers_[type][source.map_key()];
49 } else { 43 } else {
50 observer_list = new NotificationObserverList; 44 observer_list = new NotificationObserverList;
51 observers_[type.value][source.map_key()] = observer_list; 45 observers_[type][source.map_key()] = observer_list;
52 } 46 }
53 47
54 observer_list->AddObserver(observer); 48 observer_list->AddObserver(observer);
55 #ifndef NDEBUG 49 #ifndef NDEBUG
56 ++observer_counts_[type.value]; 50 ++observer_counts_[type];
57 #endif 51 #endif
58 } 52 }
59 53
60 void NotificationService::RemoveObserver(NotificationObserver* observer, 54 void NotificationService::RemoveObserver(NotificationObserver* observer,
61 NotificationType type, 55 int type,
62 const NotificationSource& source) { 56 const NotificationSource& source) {
63 DCHECK(type.value < NotificationType::NOTIFICATION_TYPE_COUNT);
64
65 // This is a very serious bug. An object is most likely being deleted on 57 // This is a very serious bug. An object is most likely being deleted on
66 // the wrong thread, and as a result another thread's NotificationService 58 // the wrong thread, and as a result another thread's NotificationService
67 // has its deleted pointer in its map. A garbge object will be called in the 59 // has its deleted pointer in its map. A garbge object will be called in the
68 // future. 60 // future.
69 // NOTE: when this check shows crashes, use BrowserThread::DeleteOnIOThread or 61 // NOTE: when this check shows crashes, use BrowserThread::DeleteOnIOThread or
70 // other variants as the trait on the object. 62 // other variants as the trait on the object.
71 CHECK(HasKey(observers_[type.value], source)); 63 CHECK(HasKey(observers_[type], source));
72 64
73 NotificationObserverList* observer_list = 65 NotificationObserverList* observer_list =
74 observers_[type.value][source.map_key()]; 66 observers_[type][source.map_key()];
75 if (observer_list) { 67 if (observer_list) {
76 observer_list->RemoveObserver(observer); 68 observer_list->RemoveObserver(observer);
77 #ifndef NDEBUG 69 #ifndef NDEBUG
78 --observer_counts_[type.value]; 70 --observer_counts_[type];
79 #endif 71 #endif
80 } 72 }
81 73
82 // TODO(jhughes): Remove observer list from map if empty? 74 // TODO(jhughes): Remove observer list from map if empty?
83 } 75 }
84 76
85 void NotificationService::Notify(NotificationType type, 77 void NotificationService::Notify(int type,
86 const NotificationSource& source, 78 const NotificationSource& source,
87 const NotificationDetails& details) { 79 const NotificationDetails& details) {
88 DCHECK(type.value > NotificationType::ALL) << 80 DCHECK(type > content::NOTIFICATION_ALL) <<
89 "Allowed for observing, but not posting."; 81 "Allowed for observing, but not posting.";
90 DCHECK(type.value < NotificationType::NOTIFICATION_TYPE_COUNT);
91 82
92 // There's no particular reason for the order in which the different 83 // There's no particular reason for the order in which the different
93 // classes of observers get notified here. 84 // classes of observers get notified here.
94 85
95 // Notify observers of all types and all sources 86 // Notify observers of all types and all sources
96 if (HasKey(observers_[NotificationType::ALL], AllSources()) && 87 if (HasKey(observers_[content::NOTIFICATION_ALL], AllSources()) &&
97 source != AllSources()) { 88 source != AllSources()) {
98 FOR_EACH_OBSERVER(NotificationObserver, 89 FOR_EACH_OBSERVER(NotificationObserver,
99 *observers_[NotificationType::ALL][AllSources().map_key()], 90 *observers_[content::NOTIFICATION_ALL][AllSources().map_key()],
100 Observe(type, source, details)); 91 Observe(type, source, details));
101 } 92 }
102 93
103 // Notify observers of all types and the given source 94 // Notify observers of all types and the given source
104 if (HasKey(observers_[NotificationType::ALL], source)) { 95 if (HasKey(observers_[content::NOTIFICATION_ALL], source)) {
105 FOR_EACH_OBSERVER(NotificationObserver, 96 FOR_EACH_OBSERVER(NotificationObserver,
106 *observers_[NotificationType::ALL][source.map_key()], 97 *observers_[content::NOTIFICATION_ALL][source.map_key()],
107 Observe(type, source, details)); 98 Observe(type, source, details));
108 } 99 }
109 100
110 // Notify observers of the given type and all sources 101 // Notify observers of the given type and all sources
111 if (HasKey(observers_[type.value], AllSources()) && 102 if (HasKey(observers_[type], AllSources()) &&
112 source != AllSources()) { 103 source != AllSources()) {
113 FOR_EACH_OBSERVER(NotificationObserver, 104 FOR_EACH_OBSERVER(NotificationObserver,
114 *observers_[type.value][AllSources().map_key()], 105 *observers_[type][AllSources().map_key()],
115 Observe(type, source, details)); 106 Observe(type, source, details));
116 } 107 }
117 108
118 // Notify observers of the given type and the given source 109 // Notify observers of the given type and the given source
119 if (HasKey(observers_[type.value], source)) { 110 if (HasKey(observers_[type], source)) {
120 FOR_EACH_OBSERVER(NotificationObserver, 111 FOR_EACH_OBSERVER(NotificationObserver,
121 *observers_[type.value][source.map_key()], 112 *observers_[type][source.map_key()],
122 Observe(type, source, details)); 113 Observe(type, source, details));
123 } 114 }
124 } 115 }
125 116
126 117
127 NotificationService::~NotificationService() { 118 NotificationService::~NotificationService() {
128 lazy_tls_ptr.Pointer()->Set(NULL); 119 lazy_tls_ptr.Pointer()->Set(NULL);
129 120
130 #ifndef NDEBUG 121 #ifndef NDEBUG
131 for (int i = 0; i < NotificationType::NOTIFICATION_TYPE_COUNT; i++) { 122 for (size_t i = 0; i < observer_counts_.size(); i++) {
132 if (observer_counts_[i] > 0) { 123 if (observer_counts_[i] > 0) {
133 // This may not be completely fixable -- see 124 // This may not be completely fixable -- see
134 // http://code.google.com/p/chromium/issues/detail?id=11010 . 125 // http://code.google.com/p/chromium/issues/detail?id=11010 .
135 VLOG(1) << observer_counts_[i] << " notification observer(s) leaked " 126 VLOG(1) << observer_counts_[i] << " notification observer(s) leaked "
136 "of notification type " << i; 127 "of notification type " << i;
137 } 128 }
138 } 129 }
139 #endif 130 #endif
140 131
141 for (int i = 0; i < NotificationType::NOTIFICATION_TYPE_COUNT; i++) { 132 for (size_t i = 0; i < observers_.size(); i++) {
142 NotificationSourceMap omap = observers_[i]; 133 NotificationSourceMap omap = observers_[i];
143 for (NotificationSourceMap::iterator it = omap.begin(); 134 for (NotificationSourceMap::iterator it = omap.begin();
144 it != omap.end(); ++it) 135 it != omap.end(); ++it)
145 delete it->second; 136 delete it->second;
146 } 137 }
147 } 138 }
148 139
149 NotificationObserver::NotificationObserver() {} 140 NotificationObserver::NotificationObserver() {}
150 141
151 NotificationObserver::~NotificationObserver() {} 142 NotificationObserver::~NotificationObserver() {}
OLDNEW
« no previous file with comments | « content/common/notification_service.h ('k') | content/common/notification_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698