OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/common/notification_service.h" | 5 #include "chrome/common/notification_service.h" |
6 | 6 |
7 // TODO(evanm): This shouldn't depend on static initialization. | 7 #include "base/lazy_instance.h" |
| 8 #include "base/thread_local.h" |
| 9 |
| 10 static base::LazyInstance<base::ThreadLocalPointer<NotificationService> > |
| 11 lazy_tls_ptr(base::LINKER_INITIALIZED); |
| 12 |
8 // static | 13 // static |
9 TLSSlot NotificationService::tls_index_; | 14 NotificationService* NotificationService::current() { |
| 15 return lazy_tls_ptr.Pointer()->Get(); |
| 16 } |
10 | 17 |
11 // static | 18 // static |
12 bool NotificationService::HasKey(const NotificationSourceMap& map, | 19 bool NotificationService::HasKey(const NotificationSourceMap& map, |
13 const NotificationSource& source) { | 20 const NotificationSource& source) { |
14 return map.find(source.map_key()) != map.end(); | 21 return map.find(source.map_key()) != map.end(); |
15 } | 22 } |
16 | 23 |
17 NotificationService::NotificationService() { | 24 NotificationService::NotificationService() { |
18 DCHECK(current() == NULL); | 25 DCHECK(current() == NULL); |
19 #ifndef NDEBUG | 26 #ifndef NDEBUG |
20 memset(observer_counts_, 0, sizeof(observer_counts_)); | 27 memset(observer_counts_, 0, sizeof(observer_counts_)); |
21 #endif | 28 #endif |
22 | 29 |
23 tls_index_.Set(this); | 30 lazy_tls_ptr.Pointer()->Set(this); |
24 } | 31 } |
25 | 32 |
26 void NotificationService::AddObserver(NotificationObserver* observer, | 33 void NotificationService::AddObserver(NotificationObserver* observer, |
27 NotificationType type, | 34 NotificationType type, |
28 const NotificationSource& source) { | 35 const NotificationSource& source) { |
29 DCHECK(type < NOTIFICATION_TYPE_COUNT); | 36 DCHECK(type < NOTIFICATION_TYPE_COUNT); |
30 | 37 |
31 NotificationObserverList* observer_list; | 38 NotificationObserverList* observer_list; |
32 if (HasKey(observers_[type], source)) { | 39 if (HasKey(observers_[type], source)) { |
33 observer_list = observers_[type][source.map_key()]; | 40 observer_list = observers_[type][source.map_key()]; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 Observe(type, source, details)); | 94 Observe(type, source, details)); |
88 // Notify observers of the given type and the given source | 95 // Notify observers of the given type and the given source |
89 if (HasKey(observers_[type], source)) | 96 if (HasKey(observers_[type], source)) |
90 FOR_EACH_OBSERVER(NotificationObserver, | 97 FOR_EACH_OBSERVER(NotificationObserver, |
91 *observers_[type][source.map_key()], | 98 *observers_[type][source.map_key()], |
92 Observe(type, source, details)); | 99 Observe(type, source, details)); |
93 } | 100 } |
94 | 101 |
95 | 102 |
96 NotificationService::~NotificationService() { | 103 NotificationService::~NotificationService() { |
97 tls_index_.Set(NULL); | 104 lazy_tls_ptr.Pointer()->Set(NULL); |
98 | 105 |
99 #ifndef NDEBUG | 106 #ifndef NDEBUG |
100 for (int i = 0; i < NOTIFICATION_TYPE_COUNT; i++) { | 107 for (int i = 0; i < NOTIFICATION_TYPE_COUNT; i++) { |
101 if (observer_counts_[i] > 0) { | 108 if (observer_counts_[i] > 0) { |
102 LOG(WARNING) << observer_counts_[i] << " notification observer(s) leaked" | 109 LOG(WARNING) << observer_counts_[i] << " notification observer(s) leaked" |
103 << " of notification type " << i; | 110 << " of notification type " << i; |
104 } | 111 } |
105 } | 112 } |
106 #endif | 113 #endif |
107 | 114 |
108 for (int i = 0; i < NOTIFICATION_TYPE_COUNT; i++) { | 115 for (int i = 0; i < NOTIFICATION_TYPE_COUNT; i++) { |
109 NotificationSourceMap omap = observers_[i]; | 116 NotificationSourceMap omap = observers_[i]; |
110 for (NotificationSourceMap::iterator it = omap.begin(); | 117 for (NotificationSourceMap::iterator it = omap.begin(); |
111 it != omap.end(); ++it) { | 118 it != omap.end(); ++it) { |
112 delete it->second; | 119 delete it->second; |
113 } | 120 } |
114 } | 121 } |
115 } | 122 } |
116 | 123 |
117 NotificationObserver::~NotificationObserver() {} | 124 NotificationObserver::~NotificationObserver() {} |
118 | 125 |
OLD | NEW |