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
13fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // the same Flag take place on the same sequenced thread.
14fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checker_.DetachFromSequence();
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.
20fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  DCHECK(sequence_checker_.CalledOnValidSequencedThread() || HasOneRef())
21fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      << "WeakPtrs must be invalidated on the same sequenced thread.";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_valid_ = false;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WeakReference::Flag::IsValid() const {
26fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  DCHECK(sequence_checker_.CalledOnValidSequencedThread())
27fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      << "WeakPtrs must be checked on the same sequenced 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)
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool WeakReference::is_valid() const { return flag_.get() && flag_->IsValid(); }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReferenceOwner::WeakReferenceOwner() {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReferenceOwner::~WeakReferenceOwner() {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Invalidate();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakReference WeakReferenceOwner::GetRef() const {
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If we hold the last reference to the Flag then create a new one.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasRefs())
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flag_ = new WeakReference::Flag();
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return WeakReference(flag_.get());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WeakReferenceOwner::Invalidate() {
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (flag_.get()) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flag_->Invalidate();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flag_ = NULL;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakPtrBase::WeakPtrBase() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakPtrBase::~WeakPtrBase() {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
78