diff options
author | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:53:36 +0900 |
---|---|---|
committer | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:53:36 +0900 |
commit | 74e42fb0242c25c1fa46e45fcf04e3c88ab40620 (patch) | |
tree | ebbbe8a8120031a0a1340161064b1e1a2b2bc2ef /base/memory/ref_counted.cc | |
parent | 98fbfad8ece16f88391165f4ad849e87e246bbdb (diff) | |
download | chromium-74e42fb0242c25c1fa46e45fcf04e3c88ab40620.tar.gz chromium-74e42fb0242c25c1fa46e45fcf04e3c88ab40620.tar.bz2 chromium-74e42fb0242c25c1fa46e45fcf04e3c88ab40620.zip |
Diffstat (limited to 'base/memory/ref_counted.cc')
-rw-r--r-- | base/memory/ref_counted.cc | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/base/memory/ref_counted.cc b/base/memory/ref_counted.cc new file mode 100644 index 000000000000..31ad5098cd0f --- /dev/null +++ b/base/memory/ref_counted.cc @@ -0,0 +1,95 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/memory/ref_counted.h" + +#include "base/logging.h" +#include "base/threading/thread_collision_warner.h" + +namespace base { + +namespace subtle { + +RefCountedBase::RefCountedBase() + : ref_count_(0) +#ifndef NDEBUG + , in_dtor_(false) +#endif + { +} + +RefCountedBase::~RefCountedBase() { +#ifndef NDEBUG + DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; +#endif +} + +void RefCountedBase::AddRef() const { + // TODO(maruel): Add back once it doesn't assert 500 times/sec. + // Current thread books the critical section "AddRelease" without release it. + // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); +#ifndef NDEBUG + DCHECK(!in_dtor_); +#endif + ++ref_count_; +} + +bool RefCountedBase::Release() const { + // TODO(maruel): Add back once it doesn't assert 500 times/sec. + // Current thread books the critical section "AddRelease" without release it. + // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); +#ifndef NDEBUG + DCHECK(!in_dtor_); +#endif + if (--ref_count_ == 0) { +#ifndef NDEBUG + in_dtor_ = true; +#endif + return true; + } + return false; +} + +bool RefCountedThreadSafeBase::HasOneRef() const { + return AtomicRefCountIsOne( + &const_cast<RefCountedThreadSafeBase*>(this)->ref_count_); +} + +RefCountedThreadSafeBase::RefCountedThreadSafeBase() : ref_count_(0) { +#ifndef NDEBUG + in_dtor_ = false; +#endif +} + +RefCountedThreadSafeBase::~RefCountedThreadSafeBase() { +#ifndef NDEBUG + DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without " + "calling Release()"; +#endif +} + +void RefCountedThreadSafeBase::AddRef() const { +#ifndef NDEBUG + DCHECK(!in_dtor_); +#endif + AtomicRefCountInc(&ref_count_); +} + +bool RefCountedThreadSafeBase::Release() const { +#ifndef NDEBUG + DCHECK(!in_dtor_); + DCHECK(!AtomicRefCountIsZero(&ref_count_)); +#endif + if (!AtomicRefCountDec(&ref_count_)) { +#ifndef NDEBUG + in_dtor_ = true; +#endif + return true; + } + return false; +} + +} // namespace subtle + +} // namespace base |