All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
refBase.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_TF_REF_BASE_H
8#define PXR_BASE_TF_REF_BASE_H
9
12
13#include "pxr/pxr.h"
14
15#include "pxr/base/tf/api.h"
16
17#include <atomic>
18#include <cmath>
19
20PXR_NAMESPACE_OPEN_SCOPE
21
22template <class T> class TfRefPtr;
23template <class T> class TfWeakPtr;
24
56class TfRefBase {
57public:
58
59 typedef void (*UniqueChangedFuncPtr)(TfRefBase const *, bool);
60 struct UniqueChangedListener {
61 void (*lock)();
62 UniqueChangedFuncPtr func;
63 void (*unlock)();
64 };
65
66 // This mimics the old TfRefCount's default ctor behavior, which set
67 // _refCount to 1.
68 TfRefBase() : _refCount(1) {}
69
70 // This mimics the old TfRefCount's copy ctor behavior, which set _refCount
71 // to 1 on copy construction.
72 TfRefBase(TfRefBase const &) : _refCount(1) {}
73
74 // This mimics the old TfRefCount's copy assignment behavior, which took no
75 // action.
76 TfRefBase &operator=(TfRefBase const &) {
77 return *this;
78 }
79
81 size_t GetCurrentCount() const {
82 // Return the absolute value since the sign encodes whether or not this
83 // TfRefBase invokes the UniqueChangedListener.
84 return std::abs(_refCount.load(std::memory_order_relaxed));
85 }
86
88 bool IsUnique() const {
89 return GetCurrentCount() == 1;
90 }
91
92 void SetShouldInvokeUniqueChangedListener(bool shouldCall) {
93 int curValue = _refCount.load(std::memory_order_relaxed);
94 while ((curValue > 0 && shouldCall) ||
95 (curValue < 0 && !shouldCall)) {
96 if (_refCount.compare_exchange_weak(curValue, -curValue)) {
97 return;
98 }
99 }
100 }
101
102 TF_API static void SetUniqueChangedListener(UniqueChangedListener listener);
103
104protected:
105 /*
106 * Prohibit deletion through a TfRefBase pointer.
107 */
108 TF_API virtual ~TfRefBase();
109
110private:
111 // For TfRefPtr's use.
112 std::atomic_int &_GetRefCount() const {
113 return _refCount;
114 }
115
116 // Note! Counts can be both positive or negative. Negative counts indicate
117 // that we must invoke the _uniqueChangedListener if the count goes 1 -> 2
118 // or 2 -> 1 (which is really -1 -> -2 or -2 -> -1).
119 mutable std::atomic_int _refCount;
120
121 static UniqueChangedListener _uniqueChangedListener;
122 template <typename T> friend class TfRefPtr;
123 friend struct Tf_RefPtr_UniqueChangedCounter;
124 friend struct Tf_RefPtr_Counter;
125
126 template <typename T> friend TfRefPtr<T>
128};
129
140public:
141 TF_API virtual ~TfSimpleRefBase();
142};
143
144PXR_NAMESPACE_CLOSE_SCOPE
145
146#endif // PXR_BASE_TF_REF_BASE_H
Enable a concrete base class for use with TfRefPtr.
Definition: refBase.h:56
friend TfRefPtr< T > TfCreateRefPtrFromProtectedWeakPtr(TfWeakPtr< T > const &)
Thread-safe creation of a Tf ref pointer from a Tf weak pointer.
Definition: weakPtr.h:260
bool IsUnique() const
Return true if only one TfRefPtr points to this object.
Definition: refBase.h:88
size_t GetCurrentCount() const
Return the current reference count of this object.
Definition: refBase.h:81
Reference-counted smart pointer utility class.
Definition: refPtr.h:590
Enable a concrete base class for use with TfRefPtr that inhibits the "unique changed" facility of TfR...
Definition: refBase.h:139
Pointer storage with deletion detection.
Definition: weakPtr.h:128