summaryrefslogtreecommitdiffstats
path: root/base/observer_list.h
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-09 03:41:18 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-09 03:41:18 +0000
commit671b74df4a8a16ca0c107dec6f7527e51d6ebfbf (patch)
tree05361ae3229d6a41892edf5ad9ae5795b7e97597 /base/observer_list.h
parente0a364209b0da8378accf3f28d3a850a26eeb0dd (diff)
downloadchromium_src-671b74df4a8a16ca0c107dec6f7527e51d6ebfbf.zip
chromium_src-671b74df4a8a16ca0c107dec6f7527e51d6ebfbf.tar.gz
chromium_src-671b74df4a8a16ca0c107dec6f7527e51d6ebfbf.tar.bz2
Revert 88284 - Revert 88151 (see crbug.com/85296) - Fix user-after-free error with ObserverList. The problem is that if an ObserverListBase::Iterator is on the stack and one of the observers deletes the object holding the list, Iterator's destructor will use the deleted list.
Relanding 88151 now that sync fixes (88483, 88472) are in. BUG=84919 Review URL: http://codereview.chromium.org/7127001 TBR=jam@chromium.org Review URL: http://codereview.chromium.org/7134008 TBR=thakis@chromium.org Review URL: http://codereview.chromium.org/7129036 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@88484 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/observer_list.h')
-rw-r--r--base/observer_list.h18
1 files changed, 11 insertions, 7 deletions
diff --git a/base/observer_list.h b/base/observer_list.h
index b8c2ae4..d30cc6e 100644
--- a/base/observer_list.h
+++ b/base/observer_list.h
@@ -12,6 +12,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
///////////////////////////////////////////////////////////////////////////////
//
@@ -61,7 +62,8 @@ template <typename ObserverType>
class ObserverListThreadSafe;
template <class ObserverType>
-class ObserverListBase {
+class ObserverListBase
+ : public base::SupportsWeakPtr<ObserverListBase<ObserverType> > {
public:
// Enumeration of which observers are notified.
enum NotificationType {
@@ -79,21 +81,23 @@ class ObserverListBase {
class Iterator {
public:
Iterator(ObserverListBase<ObserverType>& list)
- : list_(list),
+ : list_(list.AsWeakPtr()),
index_(0),
max_index_(list.type_ == NOTIFY_ALL ?
std::numeric_limits<size_t>::max() :
list.observers_.size()) {
- ++list_.notify_depth_;
+ ++list_->notify_depth_;
}
~Iterator() {
- if (--list_.notify_depth_ == 0)
- list_.Compact();
+ if (list_ && --list_->notify_depth_ == 0)
+ list_->Compact();
}
ObserverType* GetNext() {
- ListType& observers = list_.observers_;
+ if (!list_)
+ return NULL;
+ ListType& observers = list_->observers_;
// Advance if the current element is null
size_t max_index = std::min(max_index_, observers.size());
while (index_ < max_index && !observers[index_])
@@ -102,7 +106,7 @@ class ObserverListBase {
}
private:
- ObserverListBase<ObserverType>& list_;
+ base::WeakPtr<ObserverListBase<ObserverType> > list_;
size_t index_;
size_t max_index_;
};