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

Side by Side Diff: base/observer_list.h

Issue 7134008: Revert 88151 (see crbug.com/85296) - Fix user-after-free error with ObserverList. The problem is... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 6 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 | « no previous file | base/observer_list_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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_H__ 5 #ifndef BASE_OBSERVER_LIST_H__
6 #define BASE_OBSERVER_LIST_H__ 6 #define BASE_OBSERVER_LIST_H__
7 #pragma once 7 #pragma once
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <limits> 10 #include <limits>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/weak_ptr.h"
16 15
17 /////////////////////////////////////////////////////////////////////////////// 16 ///////////////////////////////////////////////////////////////////////////////
18 // 17 //
19 // OVERVIEW: 18 // OVERVIEW:
20 // 19 //
21 // A container for a list of observers. Unlike a normal STL vector or list, 20 // A container for a list of observers. Unlike a normal STL vector or list,
22 // this container can be modified during iteration without invalidating the 21 // this container can be modified during iteration without invalidating the
23 // iterator. So, it safely handles the case of an observer removing itself 22 // iterator. So, it safely handles the case of an observer removing itself
24 // or other observers from the list while observers are being notified. 23 // or other observers from the list while observers are being notified.
25 // 24 //
(...skipping 29 matching lines...) Expand all
55 // ObserverList<Observer> observer_list_; 54 // ObserverList<Observer> observer_list_;
56 // }; 55 // };
57 // 56 //
58 // 57 //
59 /////////////////////////////////////////////////////////////////////////////// 58 ///////////////////////////////////////////////////////////////////////////////
60 59
61 template <typename ObserverType> 60 template <typename ObserverType>
62 class ObserverListThreadSafe; 61 class ObserverListThreadSafe;
63 62
64 template <class ObserverType> 63 template <class ObserverType>
65 class ObserverListBase 64 class ObserverListBase {
66 : public base::SupportsWeakPtr<ObserverListBase<ObserverType> > {
67 public: 65 public:
68 // Enumeration of which observers are notified. 66 // Enumeration of which observers are notified.
69 enum NotificationType { 67 enum NotificationType {
70 // Specifies that any observers added during notification are notified. 68 // Specifies that any observers added during notification are notified.
71 // This is the default type if non type is provided to the constructor. 69 // This is the default type if non type is provided to the constructor.
72 NOTIFY_ALL, 70 NOTIFY_ALL,
73 71
74 // Specifies that observers added while sending out notification are not 72 // Specifies that observers added while sending out notification are not
75 // notified. 73 // notified.
76 NOTIFY_EXISTING_ONLY 74 NOTIFY_EXISTING_ONLY
77 }; 75 };
78 76
79 // An iterator class that can be used to access the list of observers. See 77 // An iterator class that can be used to access the list of observers. See
80 // also the FOR_EACH_OBSERVER macro defined below. 78 // also the FOR_EACH_OBSERVER macro defined below.
81 class Iterator { 79 class Iterator {
82 public: 80 public:
83 Iterator(ObserverListBase<ObserverType>& list) 81 Iterator(ObserverListBase<ObserverType>& list)
84 : list_(list.AsWeakPtr()), 82 : list_(list),
85 index_(0), 83 index_(0),
86 max_index_(list.type_ == NOTIFY_ALL ? 84 max_index_(list.type_ == NOTIFY_ALL ?
87 std::numeric_limits<size_t>::max() : 85 std::numeric_limits<size_t>::max() :
88 list.observers_.size()) { 86 list.observers_.size()) {
89 ++list_->notify_depth_; 87 ++list_.notify_depth_;
90 } 88 }
91 89
92 ~Iterator() { 90 ~Iterator() {
93 if (list_ && --list_->notify_depth_ == 0) 91 if (--list_.notify_depth_ == 0)
94 list_->Compact(); 92 list_.Compact();
95 } 93 }
96 94
97 ObserverType* GetNext() { 95 ObserverType* GetNext() {
98 if (!list_) 96 ListType& observers = list_.observers_;
99 return NULL;
100 ListType& observers = list_->observers_;
101 // Advance if the current element is null 97 // Advance if the current element is null
102 size_t max_index = std::min(max_index_, observers.size()); 98 size_t max_index = std::min(max_index_, observers.size());
103 while (index_ < max_index && !observers[index_]) 99 while (index_ < max_index && !observers[index_])
104 ++index_; 100 ++index_;
105 return index_ < max_index ? observers[index_++] : NULL; 101 return index_ < max_index ? observers[index_++] : NULL;
106 } 102 }
107 103
108 private: 104 private:
109 base::WeakPtr<ObserverListBase<ObserverType> > list_; 105 ObserverListBase<ObserverType>& list_;
110 size_t index_; 106 size_t index_;
111 size_t max_index_; 107 size_t max_index_;
112 }; 108 };
113 109
114 ObserverListBase() : notify_depth_(0), type_(NOTIFY_ALL) {} 110 ObserverListBase() : notify_depth_(0), type_(NOTIFY_ALL) {}
115 explicit ObserverListBase(NotificationType type) 111 explicit ObserverListBase(NotificationType type)
116 : notify_depth_(0), type_(type) {} 112 : notify_depth_(0), type_(type) {}
117 113
118 // Add an observer to the list. An observer should not be added to 114 // Add an observer to the list. An observer should not be added to
119 // the same list more than once. 115 // the same list more than once.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 203
208 #define FOR_EACH_OBSERVER(ObserverType, observer_list, func) \ 204 #define FOR_EACH_OBSERVER(ObserverType, observer_list, func) \
209 do { \ 205 do { \
210 ObserverListBase<ObserverType>::Iterator it(observer_list); \ 206 ObserverListBase<ObserverType>::Iterator it(observer_list); \
211 ObserverType* obs; \ 207 ObserverType* obs; \
212 while ((obs = it.GetNext()) != NULL) \ 208 while ((obs = it.GetNext()) != NULL) \
213 obs->func; \ 209 obs->func; \
214 } while (0) 210 } while (0)
215 211
216 #endif // BASE_OBSERVER_LIST_H__ 212 #endif // BASE_OBSERVER_LIST_H__
OLDNEW
« no previous file with comments | « no previous file | base/observer_list_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698