From d6d404c2d3a9b60402588fe934b734b3417e2259 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Sun, 16 Jun 2013 22:05:14 -0400 Subject: [PATCH] Bug 882561 - Add a GenericRefCounted base class to moz2d, will allow moz2d to hold strong references to external objects without adding a dependency r=jwalden --- gfx/2d/GenericRefCounted.h | 102 +++++++++++++++++++++++++++++++++++++ gfx/2d/moz.build | 4 ++ 2 files changed, 106 insertions(+) create mode 100644 gfx/2d/GenericRefCounted.h diff --git a/gfx/2d/GenericRefCounted.h b/gfx/2d/GenericRefCounted.h new file mode 100644 index 00000000000..b82f5ec3d16 --- /dev/null +++ b/gfx/2d/GenericRefCounted.h @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This header provides virtual, non-templated alternatives to MFBT's RefCounted. +// It intentionally uses MFBT coding style with the intention of moving there +// should there be other use cases for it. + +#ifndef MOZILLA_GENERICREFCOUNTED_H_ +#define MOZILLA_GENERICREFCOUNTED_H_ + +#include "mozilla/RefPtr.h" + +namespace mozilla { + +/** + * Common base class for GenericRefCounted and GenericAtomicRefCounted. + * + * Having this shared base class, common to both the atomic and non-atomic + * cases, allows to have RefPtr's that don't care about whether the + * objects they're managing have atomic refcounts or not. + */ +class GenericRefCountedBase +{ + protected: + virtual ~GenericRefCountedBase() {}; + + public: + // AddRef() and Release() method names are for compatibility with nsRefPtr. + virtual void AddRef() = 0; + + virtual void Release() = 0; + + // ref() and deref() method names are for compatibility with wtf::RefPtr. + // No virtual keywords here: if a subclass wants to override the refcounting + // mechanism, it is welcome to do so by overriding AddRef() and Release(). + void ref() { AddRef(); } + void deref() { Release(); } +}; + +namespace detail { + +template +class GenericRefCounted : public GenericRefCountedBase +{ + protected: + GenericRefCounted() : refCnt(0) { } + + virtual ~GenericRefCounted() { + MOZ_ASSERT(refCnt == detail::DEAD); + } + + public: + virtual void AddRef() { + MOZ_ASSERT(refCnt >= 0); + ++refCnt; + } + + virtual void Release() { + MOZ_ASSERT(refCnt > 0); + if (0 == --refCnt) { +#ifdef DEBUG + refCnt = detail::DEAD; +#endif + delete this; + } + } + + int refCount() const { return refCnt; } + bool hasOneRef() const { + MOZ_ASSERT(refCnt > 0); + return refCnt == 1; + } + + private: + typename Conditional, int>::Type refCnt; +}; + +} // namespace detail + +/** + * This reference-counting base class is virtual instead of + * being templated, which is useful in cases where one needs + * genericity at binary code level, but comes at the cost + * of a moderate performance and size overhead, like anything virtual. + */ +class GenericRefCounted : public detail::GenericRefCounted +{ +}; + +/** + * GenericAtomicRefCounted is like GenericRefCounted, with an atomically updated + * reference counter. + */ +class GenericAtomicRefCounted : public detail::GenericRefCounted +{ +}; + +} // namespace mozilla + +#endif diff --git a/gfx/2d/moz.build b/gfx/2d/moz.build index d74a0c2db97..f49078abda2 100644 --- a/gfx/2d/moz.build +++ b/gfx/2d/moz.build @@ -6,6 +6,10 @@ MODULE = 'gfx2d' +EXPORTS.mozilla += [ + 'GenericRefCounted.h', +] + EXPORTS.mozilla.gfx += [ '2D.h', 'BaseMargin.h',