diff options
author | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-23 12:14:24 +0000 |
---|---|---|
committer | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-23 12:14:24 +0000 |
commit | eff4d5c9829deab6cda2323fcb6068335b371436 (patch) | |
tree | d9a329ed55d975d03d07534e8a6a58514ae0a3e9 /base/memory/weak_ptr.cc | |
parent | 9e9a1743db15851b86086fc7486dd70ce07027f0 (diff) | |
download | chromium_src-eff4d5c9829deab6cda2323fcb6068335b371436.zip chromium_src-eff4d5c9829deab6cda2323fcb6068335b371436.tar.gz chromium_src-eff4d5c9829deab6cda2323fcb6068335b371436.tar.bz2 |
Revert 97808 - Make WeakPtr thread-safe, i.e. allow cross-thread copying of WeakPtr
and destruction on a thread other than the one where the original
reference was created.
The problem with the current implementation is modifying the flag pointer
from WeakPtr::~WeakPtr which might happen on a different thread (potentially
racing with somebody invalidating the flag on the original thread).
For compatibility reasons, creating the initial reference attaches to the
thread and governs the thread-safety checking logic with respect to checking
a reference to be valid and invalidating it, which should both only be done
on the same thread.
BUG=82509
TEST=added unit tests
Review URL: http://codereview.chromium.org/7677028
TBR=sievers@chromium.org
Review URL: http://codereview.chromium.org/7685054
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97846 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/memory/weak_ptr.cc')
-rw-r--r-- | base/memory/weak_ptr.cc | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/base/memory/weak_ptr.cc b/base/memory/weak_ptr.cc index 9dec8fd..30c777c 100644 --- a/base/memory/weak_ptr.cc +++ b/base/memory/weak_ptr.cc @@ -7,28 +7,28 @@ namespace base { namespace internal { -WeakReference::Flag::Flag() : is_valid_(true) { +WeakReference::Flag::Flag(Flag** handle) : handle_(handle) { } void WeakReference::Flag::Invalidate() { - // The flag being invalidated with a single ref implies that there are no - // weak pointers in existence. Allow deletion on other thread in this case. - DCHECK(thread_checker_.CalledOnValidThread() || HasOneRef()); - is_valid_ = false; + DCHECK(thread_checker_.CalledOnValidThread()); + handle_ = NULL; } bool WeakReference::Flag::IsValid() const { DCHECK(thread_checker_.CalledOnValidThread()); - return is_valid_; + return handle_ != NULL; } WeakReference::Flag::~Flag() { + if (handle_) + *handle_ = NULL; } WeakReference::WeakReference() { } -WeakReference::WeakReference(const Flag* flag) : flag_(flag) { +WeakReference::WeakReference(Flag* flag) : flag_(flag) { } WeakReference::~WeakReference() { @@ -38,7 +38,7 @@ bool WeakReference::is_valid() const { return flag_ && flag_->IsValid(); } -WeakReferenceOwner::WeakReferenceOwner() { +WeakReferenceOwner::WeakReferenceOwner() : flag_(NULL) { } WeakReferenceOwner::~WeakReferenceOwner() { @@ -46,10 +46,8 @@ WeakReferenceOwner::~WeakReferenceOwner() { } WeakReference WeakReferenceOwner::GetRef() const { - // We also want to reattach to the current thread if all previous references - // have gone away. - if (!HasRefs()) - flag_ = new WeakReference::Flag(); + if (!flag_) + flag_ = new WeakReference::Flag(&flag_); return WeakReference(flag_); } |