// Copyright (c) 2012 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. #ifndef LIBRARIES_SDK_UTIL_REF_OBJECT #define LIBRARIES_SDK_UTIL_REF_OBJECT #include <stdlib.h> #include "pthread.h" #include "sdk_util/atomicops.h" namespace sdk_util { class ScopedRefBase; /* * RefObject * * A reference counted object. RefObjects should only be handled by ScopedRef * objects. * * When the object is first created, it has a reference count of zero. It's * first incremented when it gets assigned to a ScopedRef. When the last * ScopedRef is reset or destroyed the object will get released. */ class RefObject { public: RefObject() { ref_count_ = 0; } /* * RefCount * * RefCount returns an instantaneous snapshot of the RefCount, which may * change immediately after it is fetched. This is only stable when all * pointers to the object are scoped pointers (ScopedRef), and the value * is one implying the current thread is the only one, with visibility to * the object. */ int RefCount() const { return ref_count_; } protected: virtual ~RefObject() {} // Override to clean up object when last reference is released. virtual void Destroy() {} void Acquire() { AtomicAddFetch(&ref_count_, 1); } bool Release() { Atomic32 val = AtomicAddFetch(&ref_count_, -1); if (val == 0) { Destroy(); delete this; return false; } return true; } private: Atomic32 ref_count_; friend class ScopedRefBase; }; } // namespace sdk_util #endif // LIBRARIES_SDK_UTIL_REF_OBJECT