michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "base/ref_counted.h" michael@0: michael@0: #include "base/logging.h" michael@0: #include "base/thread_collision_warner.h" michael@0: michael@0: namespace base { michael@0: michael@0: namespace subtle { michael@0: michael@0: RefCountedBase::RefCountedBase() : ref_count_(0) { michael@0: #ifndef NDEBUG michael@0: in_dtor_ = false; michael@0: #endif michael@0: } michael@0: michael@0: RefCountedBase::~RefCountedBase() { michael@0: #ifndef NDEBUG michael@0: DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; michael@0: #endif michael@0: } michael@0: michael@0: void RefCountedBase::AddRef() { michael@0: // TODO(maruel): Add back once it doesn't assert 500 times/sec. michael@0: // Current thread books the critical section "AddRelease" without release it. michael@0: // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); michael@0: #ifndef NDEBUG michael@0: DCHECK(!in_dtor_); michael@0: #endif michael@0: ++ref_count_; michael@0: } michael@0: michael@0: bool RefCountedBase::Release() { michael@0: // TODO(maruel): Add back once it doesn't assert 500 times/sec. michael@0: // Current thread books the critical section "AddRelease" without release it. michael@0: // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); michael@0: #ifndef NDEBUG michael@0: DCHECK(!in_dtor_); michael@0: #endif michael@0: if (--ref_count_ == 0) { michael@0: #ifndef NDEBUG michael@0: in_dtor_ = true; michael@0: #endif michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: RefCountedThreadSafeBase::RefCountedThreadSafeBase() : ref_count_(0) { michael@0: #ifndef NDEBUG michael@0: in_dtor_ = false; michael@0: #endif michael@0: } michael@0: michael@0: RefCountedThreadSafeBase::~RefCountedThreadSafeBase() { michael@0: #ifndef NDEBUG michael@0: DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without " michael@0: "calling Release()"; michael@0: #endif michael@0: } michael@0: michael@0: void RefCountedThreadSafeBase::AddRef() { michael@0: #ifndef NDEBUG michael@0: DCHECK(!in_dtor_); michael@0: #endif michael@0: AtomicRefCountInc(&ref_count_); michael@0: } michael@0: michael@0: bool RefCountedThreadSafeBase::Release() { michael@0: #ifndef NDEBUG michael@0: DCHECK(!in_dtor_); michael@0: DCHECK(!AtomicRefCountIsZero(&ref_count_)); michael@0: #endif michael@0: if (!AtomicRefCountDec(&ref_count_)) { michael@0: #ifndef NDEBUG michael@0: in_dtor_ = true; michael@0: #endif michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: } // namespace subtle michael@0: michael@0: } // namespace base