weak_ptr.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReference::Flag::Flag() : is_valid_(true) {
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Flags only become bound when checked for validity, or invalidated,
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // so that we can check that later validity/invalidation operations on
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // the same Flag take place on the same thread.
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  thread_checker_.DetachFromThread();
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WeakReference::Flag::Invalidate() {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The flag being invalidated with a single ref implies that there are no
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // weak pointers in existence. Allow deletion on other thread in this case.
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread() || HasOneRef())
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      << "WeakPtrs must be checked and invalidated on the same thread.";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_valid_ = false;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WeakReference::Flag::IsValid() const {
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread())
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      << "WeakPtrs must be checked and invalidated on the same thread.";
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_valid_;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReference::Flag::~Flag() {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReference::WeakReference() {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReference::WeakReference(const Flag* flag) : flag_(flag) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReference::~WeakReference() {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WeakReference::is_valid() const {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return flag_ && flag_->IsValid();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReferenceOwner::WeakReferenceOwner() {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReferenceOwner::~WeakReferenceOwner() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Invalidate();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReference WeakReferenceOwner::GetRef() const {
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If we hold the last reference to the Flag then create a new one.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasRefs())
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flag_ = new WeakReference::Flag();
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WeakReference(flag_);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WeakReferenceOwner::Invalidate() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flag_) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flag_->Invalidate();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flag_ = NULL;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakPtrBase::WeakPtrBase() {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakPtrBase::~WeakPtrBase() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
80