| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Provides a base class for reference-counted classes. | |
| 6 | |
| 7 #ifndef MOJO_EDK_SYSTEM_REF_COUNTED_H_ | |
| 8 #define MOJO_EDK_SYSTEM_REF_COUNTED_H_ | |
| 9 | |
| 10 #include <assert.h> | |
| 11 | |
| 12 #include <cstddef> | |
| 13 #include <utility> | |
| 14 | |
| 15 #include "mojo/edk/system/ref_counted_internal.h" | |
| 16 #include "mojo/edk/system/ref_ptr.h" | |
| 17 #include "mojo/public/cpp/system/macros.h" | |
| 18 | |
| 19 namespace mojo { | |
| 20 namespace system { | |
| 21 | |
| 22 // A base class for (thread-safe) reference-counted classes. Use like: | |
| 23 // | |
| 24 // class Foo : public RefCountedThreadSafe<Foo> { | |
| 25 // ... | |
| 26 // }; | |
| 27 // | |
| 28 // |~Foo()| *may* be made private (e.g., to avoid accidental deletion of objects | |
| 29 // while there are still references to them), |Foo| should friend | |
| 30 // |RefCountedThreadSafe<Foo>|; use |FRIEND_REF_COUNTED_THREAD_SAFE()| for this: | |
| 31 // | |
| 32 // class Foo : public RefCountedThreadSafe<Foo> { | |
| 33 // ... | |
| 34 // private: | |
| 35 // FRIEND_REF_COUNTED_THREAD_SAFE(Foo); | |
| 36 // ~Foo(); | |
| 37 // ... | |
| 38 // }; | |
| 39 // | |
| 40 // Similarly, |Foo(...)| may be made private. In this case, there should either | |
| 41 // be a static factory method performing the requisite adoption: | |
| 42 // | |
| 43 // class Foo : public RefCountedThreadSafe<Foo> { | |
| 44 // ... | |
| 45 // public: | |
| 46 // inline static RefPtr<Foo> Create() { return AdoptRef(new Foo()); } | |
| 47 // ... | |
| 48 // private: | |
| 49 // Foo(); | |
| 50 // ... | |
| 51 // }; | |
| 52 // | |
| 53 // Or, to allow |MakeRefCounted()| to be used, use |FRIEND_MAKE_REF_COUNTED()|: | |
| 54 // | |
| 55 // class Foo : public RefCountedThreadSafe<Foo> { | |
| 56 // ... | |
| 57 // private: | |
| 58 // FRIEND_MAKE_REF_COUNTED(Foo); | |
| 59 // Foo(); | |
| 60 // Foo(const Bar& bar, bool maybe); | |
| 61 // ... | |
| 62 // }; | |
| 63 // | |
| 64 // For now, we only have thread-safe reference counting, since that's all we | |
| 65 // need. It's easy enough to add thread-unsafe versions if necessary. | |
| 66 template <typename T> | |
| 67 class RefCountedThreadSafe : public internal::RefCountedThreadSafeBase { | |
| 68 public: | |
| 69 // Adds a reference to this object. | |
| 70 // Inherited from the internal superclass: | |
| 71 // void AddRef() const; | |
| 72 | |
| 73 // Releases a reference to this object. This will destroy this object once the | |
| 74 // last reference is released. | |
| 75 void Release() const { | |
| 76 if (internal::RefCountedThreadSafeBase::Release()) | |
| 77 delete static_cast<const T*>(this); | |
| 78 } | |
| 79 | |
| 80 // Asserts that there is exactly one reference to this object; does nothing in | |
| 81 // Release builds (when |NDEBUG| is defined). | |
| 82 // Inherited from the internal superclass: | |
| 83 // void AssertHasOneRef(); | |
| 84 | |
| 85 protected: | |
| 86 // Constructor. Note that the object is constructed with a reference count of | |
| 87 // 1, and then must be adopted (see |AdoptRef()| in ref_ptr.h). | |
| 88 RefCountedThreadSafe() {} | |
| 89 | |
| 90 // Destructor. Note that this object should only be destroyed via |Release()| | |
| 91 // (see above), or something that calls |Release()| (see, e.g., |RefPtr<>| in | |
| 92 // ref_ptr.h). | |
| 93 ~RefCountedThreadSafe() {} | |
| 94 | |
| 95 private: | |
| 96 #ifndef NDEBUG | |
| 97 template <typename U> | |
| 98 friend RefPtr<U> AdoptRef(U*); | |
| 99 // Marks the initial reference (assumed on construction) as adopted. This is | |
| 100 // only required for Debug builds (when |NDEBUG| is not defined). | |
| 101 // TODO(vtl): Should this really be private? This makes manual ref-counting | |
| 102 // and also writing one's own ref pointer class impossible. | |
| 103 void Adopt() { internal::RefCountedThreadSafeBase::Adopt(); } | |
| 104 #endif | |
| 105 | |
| 106 MOJO_DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe); | |
| 107 }; | |
| 108 | |
| 109 // If you subclass |RefCountedThreadSafe| and want to keep your destructor | |
| 110 // private, use this. (See the example above |RefCountedThreadSafe|.) | |
| 111 #define FRIEND_REF_COUNTED_THREAD_SAFE(T) \ | |
| 112 friend class ::mojo::system::RefCountedThreadSafe<T> | |
| 113 | |
| 114 // If you want to keep your constructor(s) private and still want to use | |
| 115 // |MakeRefCounted<T>()|, use this. (See the example above | |
| 116 // |RefCountedThreadSafe|.) | |
| 117 #define FRIEND_MAKE_REF_COUNTED(T) \ | |
| 118 friend class ::mojo::system::internal::MakeRefCountedHelper<T> | |
| 119 | |
| 120 } // namespace system | |
| 121 } // namespace mojo | |
| 122 | |
| 123 #endif // MOJO_EDK_SYSTEM_REF_COUNTED_H_ | |
| OLD | NEW |