This document is for a version of USD that is under development. See this page for the current release.
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