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 #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 | 7 |
8 #include <vector> | 8 #include <vector> |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 } | 74 } |
75 | 75 |
76 // Remove an observer from the list. | 76 // Remove an observer from the list. |
77 // If there are pending notifications in-transit to the observer, they will | 77 // If there are pending notifications in-transit to the observer, they will |
78 // be aborted. | 78 // be aborted. |
79 // RemoveObserver MUST be called from the same thread which called | 79 // RemoveObserver MUST be called from the same thread which called |
80 // AddObserver. | 80 // AddObserver. |
81 void RemoveObserver(ObserverType* obs) { | 81 void RemoveObserver(ObserverType* obs) { |
82 ObserverList<ObserverType>* list = NULL; | 82 ObserverList<ObserverType>* list = NULL; |
83 MessageLoop* loop = MessageLoop::current(); | 83 MessageLoop* loop = MessageLoop::current(); |
| 84 if (!loop) |
| 85 return; // On shutdown, it is possible that current() is already null. |
84 { | 86 { |
85 AutoLock lock(list_lock_); | 87 AutoLock lock(list_lock_); |
86 DCHECK(observer_lists_.find(loop) != observer_lists_.end()) << | |
87 "RemoveObserver called on for unknown thread"; | |
88 list = observer_lists_[loop]; | 88 list = observer_lists_[loop]; |
| 89 if (!list) { |
| 90 NOTREACHED() << "RemoveObserver called on for unknown thread"; |
| 91 return; |
| 92 } |
89 | 93 |
90 // If we're about to remove the last observer from the list, | 94 // If we're about to remove the last observer from the list, |
91 // then we can remove this observer_list entirely. | 95 // then we can remove this observer_list entirely. |
92 if (list->size() == 1) | 96 if (list->size() == 1) |
93 observer_lists_.erase(loop); | 97 observer_lists_.erase(loop); |
94 } | 98 } |
95 list->RemoveObserver(obs); | 99 list->RemoveObserver(obs); |
96 | 100 |
97 // If RemoveObserver is called from a notification, the size will be | 101 // If RemoveObserver is called from a notification, the size will be |
98 // nonzero. Instead of deleting here, the NotifyWrapper will delete | 102 // nonzero. Instead of deleting here, the NotifyWrapper will delete |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 typedef std::map<MessageLoop*, ObserverList<ObserverType>*> ObserversListMap; | 185 typedef std::map<MessageLoop*, ObserverList<ObserverType>*> ObserversListMap; |
182 | 186 |
183 // These are marked mutable to facilitate having NotifyAll be const. | 187 // These are marked mutable to facilitate having NotifyAll be const. |
184 Lock list_lock_; // Protects the observer_lists_. | 188 Lock list_lock_; // Protects the observer_lists_. |
185 ObserversListMap observer_lists_; | 189 ObserversListMap observer_lists_; |
186 | 190 |
187 DISALLOW_EVIL_CONSTRUCTORS(ObserverListThreadSafe); | 191 DISALLOW_EVIL_CONSTRUCTORS(ObserverListThreadSafe); |
188 }; | 192 }; |
189 | 193 |
190 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_ | 194 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_ |
OLD | NEW |