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

Side by Side Diff: base/observer_list_threadsafe.h

Issue 6142009: Upating the app, ceee, chrome, ipc, media, and net directories to use the correct lock.h file. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Unified patch updating all references to the new base/synchronization/lock.h Created 9 years, 11 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 | « base/metrics/stats_table.h ('k') | base/synchronization/condition_variable.h » ('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 #ifndef BASE_OBSERVER_LIST_THREADSAFE_H_ 5 #ifndef BASE_OBSERVER_LIST_THREADSAFE_H_
6 #define BASE_OBSERVER_LIST_THREADSAFE_H_ 6 #define BASE_OBSERVER_LIST_THREADSAFE_H_
7 #pragma once 7 #pragma once
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <map> 10 #include <map>
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 // Add an observer to the list. 86 // Add an observer to the list.
87 void AddObserver(ObserverType* obs) { 87 void AddObserver(ObserverType* obs) {
88 ObserverList<ObserverType>* list = NULL; 88 ObserverList<ObserverType>* list = NULL;
89 MessageLoop* loop = MessageLoop::current(); 89 MessageLoop* loop = MessageLoop::current();
90 // TODO(mbelshe): Get rid of this check. Its needed right now because 90 // TODO(mbelshe): Get rid of this check. Its needed right now because
91 // Time currently triggers usage of the ObserverList. 91 // Time currently triggers usage of the ObserverList.
92 // And unittests use time without a MessageLoop. 92 // And unittests use time without a MessageLoop.
93 if (!loop) 93 if (!loop)
94 return; // Some unittests may access this without a message loop. 94 return; // Some unittests may access this without a message loop.
95 { 95 {
96 AutoLock lock(list_lock_); 96 base::AutoLock lock(list_lock_);
97 if (observer_lists_.find(loop) == observer_lists_.end()) 97 if (observer_lists_.find(loop) == observer_lists_.end())
98 observer_lists_[loop] = new ObserverList<ObserverType>(type_); 98 observer_lists_[loop] = new ObserverList<ObserverType>(type_);
99 list = observer_lists_[loop]; 99 list = observer_lists_[loop];
100 } 100 }
101 list->AddObserver(obs); 101 list->AddObserver(obs);
102 } 102 }
103 103
104 // Remove an observer from the list. 104 // Remove an observer from the list.
105 // If there are pending notifications in-transit to the observer, they will 105 // If there are pending notifications in-transit to the observer, they will
106 // be aborted. 106 // be aborted.
107 // RemoveObserver MUST be called from the same thread which called 107 // RemoveObserver MUST be called from the same thread which called
108 // AddObserver. 108 // AddObserver.
109 void RemoveObserver(ObserverType* obs) { 109 void RemoveObserver(ObserverType* obs) {
110 ObserverList<ObserverType>* list = NULL; 110 ObserverList<ObserverType>* list = NULL;
111 MessageLoop* loop = MessageLoop::current(); 111 MessageLoop* loop = MessageLoop::current();
112 if (!loop) 112 if (!loop)
113 return; // On shutdown, it is possible that current() is already null. 113 return; // On shutdown, it is possible that current() is already null.
114 { 114 {
115 AutoLock lock(list_lock_); 115 base::AutoLock lock(list_lock_);
116 list = observer_lists_[loop]; 116 list = observer_lists_[loop];
117 if (!list) { 117 if (!list) {
118 NOTREACHED() << "RemoveObserver called on for unknown thread"; 118 NOTREACHED() << "RemoveObserver called on for unknown thread";
119 return; 119 return;
120 } 120 }
121 121
122 // If we're about to remove the last observer from the list, 122 // If we're about to remove the last observer from the list,
123 // then we can remove this observer_list entirely. 123 // then we can remove this observer_list entirely.
124 if (list->size() == 1) 124 if (list->size() == 1)
125 observer_lists_.erase(loop); 125 observer_lists_.erase(loop);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 158
159 ~ObserverListThreadSafe() { 159 ~ObserverListThreadSafe() {
160 typename ObserversListMap::const_iterator it; 160 typename ObserversListMap::const_iterator it;
161 for (it = observer_lists_.begin(); it != observer_lists_.end(); ++it) 161 for (it = observer_lists_.begin(); it != observer_lists_.end(); ++it)
162 delete (*it).second; 162 delete (*it).second;
163 observer_lists_.clear(); 163 observer_lists_.clear();
164 } 164 }
165 165
166 template <class Method, class Params> 166 template <class Method, class Params>
167 void Notify(const UnboundMethod<ObserverType, Method, Params>& method) { 167 void Notify(const UnboundMethod<ObserverType, Method, Params>& method) {
168 AutoLock lock(list_lock_); 168 base::AutoLock lock(list_lock_);
169 typename ObserversListMap::iterator it; 169 typename ObserversListMap::iterator it;
170 for (it = observer_lists_.begin(); it != observer_lists_.end(); ++it) { 170 for (it = observer_lists_.begin(); it != observer_lists_.end(); ++it) {
171 MessageLoop* loop = (*it).first; 171 MessageLoop* loop = (*it).first;
172 ObserverList<ObserverType>* list = (*it).second; 172 ObserverList<ObserverType>* list = (*it).second;
173 loop->PostTask( 173 loop->PostTask(
174 FROM_HERE, 174 FROM_HERE,
175 NewRunnableMethod(this, 175 NewRunnableMethod(this,
176 &ObserverListThreadSafe<ObserverType>:: 176 &ObserverListThreadSafe<ObserverType>::
177 template NotifyWrapper<Method, Params>, list, method)); 177 template NotifyWrapper<Method, Params>, list, method));
178 } 178 }
179 } 179 }
180 180
181 // Wrapper which is called to fire the notifications for each thread's 181 // Wrapper which is called to fire the notifications for each thread's
182 // ObserverList. This function MUST be called on the thread which owns 182 // ObserverList. This function MUST be called on the thread which owns
183 // the unsafe ObserverList. 183 // the unsafe ObserverList.
184 template <class Method, class Params> 184 template <class Method, class Params>
185 void NotifyWrapper(ObserverList<ObserverType>* list, 185 void NotifyWrapper(ObserverList<ObserverType>* list,
186 const UnboundMethod<ObserverType, Method, Params>& method) { 186 const UnboundMethod<ObserverType, Method, Params>& method) {
187 187
188 // Check that this list still needs notifications. 188 // Check that this list still needs notifications.
189 { 189 {
190 AutoLock lock(list_lock_); 190 base::AutoLock lock(list_lock_);
191 typename ObserversListMap::iterator it = 191 typename ObserversListMap::iterator it =
192 observer_lists_.find(MessageLoop::current()); 192 observer_lists_.find(MessageLoop::current());
193 193
194 // The ObserverList could have been removed already. In fact, it could 194 // The ObserverList could have been removed already. In fact, it could
195 // have been removed and then re-added! If the master list's loop 195 // have been removed and then re-added! If the master list's loop
196 // does not match this one, then we do not need to finish this 196 // does not match this one, then we do not need to finish this
197 // notification. 197 // notification.
198 if (it == observer_lists_.end() || it->second != list) 198 if (it == observer_lists_.end() || it->second != list)
199 return; 199 return;
200 } 200 }
201 201
202 { 202 {
203 typename ObserverList<ObserverType>::Iterator it(*list); 203 typename ObserverList<ObserverType>::Iterator it(*list);
204 ObserverType* obs; 204 ObserverType* obs;
205 while ((obs = it.GetNext()) != NULL) 205 while ((obs = it.GetNext()) != NULL)
206 method.Run(obs); 206 method.Run(obs);
207 } 207 }
208 208
209 // If there are no more observers on the list, we can now delete it. 209 // If there are no more observers on the list, we can now delete it.
210 if (list->size() == 0) { 210 if (list->size() == 0) {
211 { 211 {
212 AutoLock lock(list_lock_); 212 base::AutoLock lock(list_lock_);
213 // Remove |list| if it's not already removed. 213 // Remove |list| if it's not already removed.
214 // This can happen if multiple observers got removed in a notification. 214 // This can happen if multiple observers got removed in a notification.
215 // See http://crbug.com/55725. 215 // See http://crbug.com/55725.
216 typename ObserversListMap::iterator it = 216 typename ObserversListMap::iterator it =
217 observer_lists_.find(MessageLoop::current()); 217 observer_lists_.find(MessageLoop::current());
218 if (it != observer_lists_.end() && it->second == list) 218 if (it != observer_lists_.end() && it->second == list)
219 observer_lists_.erase(it); 219 observer_lists_.erase(it);
220 } 220 }
221 delete list; 221 delete list;
222 } 222 }
223 } 223 }
224 224
225 typedef std::map<MessageLoop*, ObserverList<ObserverType>*> ObserversListMap; 225 typedef std::map<MessageLoop*, ObserverList<ObserverType>*> ObserversListMap;
226 226
227 // These are marked mutable to facilitate having NotifyAll be const. 227 // These are marked mutable to facilitate having NotifyAll be const.
228 Lock list_lock_; // Protects the observer_lists_. 228 base::Lock list_lock_; // Protects the observer_lists_.
229 ObserversListMap observer_lists_; 229 ObserversListMap observer_lists_;
230 const NotificationType type_; 230 const NotificationType type_;
231 231
232 DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe); 232 DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe);
233 }; 233 };
234 234
235 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_ 235 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_
OLDNEW
« no previous file with comments | « base/metrics/stats_table.h ('k') | base/synchronization/condition_variable.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698