All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
refPtrTracker.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_REF_PTR_TRACKER_H
25 #define PXR_BASE_TF_REF_PTR_TRACKER_H
26 
28 
29 #include "pxr/pxr.h"
30 
31 #include "pxr/base/tf/api.h"
32 #include "pxr/base/tf/hash.h"
33 #include "pxr/base/tf/hashmap.h"
34 #include "pxr/base/tf/weakBase.h"
35 #include "pxr/base/tf/singleton.h"
36 #include <boost/noncopyable.hpp>
37 #include <iosfwd>
38 #include <mutex>
39 #include <vector>
40 
41 PXR_NAMESPACE_OPEN_SCOPE
42 
43 class TfRefBase;
44 template <class T> class TfRefPtr;
45 
97 class TfRefPtrTracker : public TfWeakBase, boost::noncopyable {
98 public:
99  enum TraceType { Add, Assign };
100 
101  TF_API static TfRefPtrTracker& GetInstance()
102  {
104  }
105 
107  TF_API
108  size_t GetStackTraceMaxDepth() const;
109 
111  TF_API
112  void SetStackTraceMaxDepth(size_t);
113 
115  struct Trace {
117  std::vector<uintptr_t> trace;
118 
120  const TfRefBase* obj;
121 
123  TraceType type;
124  };
125 
127  typedef TfHashMap<const void*, Trace, TfHash> OwnerTraces;
128 
132  typedef TfHashMap<const TfRefBase*, size_t, TfHash> WatchedCounts;
133 
136  TF_API
138 
140  TF_API
141  OwnerTraces GetAllTraces() const;
142 
145  TF_API
146  void ReportAllWatchedCounts(std::ostream& stream) const;
147 
149  TF_API
150  void ReportAllTraces(std::ostream& stream) const;
151 
153  TF_API
154  void ReportTracesForWatched(std::ostream& stream,
155  const TfRefBase* watched) const;
156 
162  static bool WatchNone(const void*)
163  {
164  return false;
165  }
166 
169  static bool WatchAll(const void*)
170  {
171  return true;
172  }
173 
174 private:
175  TfRefPtrTracker();
176  ~TfRefPtrTracker();
177 
179  void _Watch(const TfRefBase* obj);
180 
182  void _Unwatch(const TfRefBase* obj);
183 
186  void _AddTrace(const void* owner, const TfRefBase* obj, TraceType = Add);
187 
189  void _RemoveTraces(const void* owner);
190 
191 private:
192  typedef std::mutex _Mutex;
193  typedef std::lock_guard<std::mutex> _Lock;
194  mutable _Mutex _mutex;
195  size_t _maxDepth;
196  WatchedCounts _watched;
197  OwnerTraces _traces;
198 
199  friend class Tf_RefPtrTrackerUtil;
200  friend class TfSingleton<TfRefPtrTracker>;
201 };
202 
203 TF_API_TEMPLATE_CLASS(TfSingleton<TfRefPtrTracker>);
204 
205 // For internal use only.
206 class Tf_RefPtrTrackerUtil {
207 public:
209  static void Watch(const TfRefBase* obj)
210  {
211  TfRefPtrTracker::GetInstance()._Watch(obj);
212  }
213 
215  static void Unwatch(const TfRefBase* obj)
216  {
217  TfRefPtrTracker::GetInstance()._Unwatch(obj);
218  }
219 
222  static void AddTrace(const void* owner, const TfRefBase* obj,
223  TfRefPtrTracker::TraceType type = TfRefPtrTracker::Add)
224  {
225  TfRefPtrTracker::GetInstance()._AddTrace(owner, obj, type);
226  }
227 
229  static void RemoveTraces(const void* owner)
230  {
231  TfRefPtrTracker::GetInstance()._RemoveTraces(owner);
232  }
233 };
234 
235 #define TF_DECLARE_REFPTR_TRACK(T) \
236 inline void Tf_RefPtrTracker_FirstRef(const void*, T* obj); \
237 inline void Tf_RefPtrTracker_LastRef(const void*, T* obj); \
238 inline void Tf_RefPtrTracker_New(const void* owner, T* obj); \
239 inline void Tf_RefPtrTracker_Delete(const void* owner, T* obj); \
240 inline void Tf_RefPtrTracker_Assign(const void* owner, T* obj, T* oldObj);
241 
242 #define TF_DEFINE_REFPTR_TRACK(T, COND) \
243 inline void Tf_RefPtrTracker_FirstRef(const void*, T* obj) { \
244  if (obj && COND(obj)) Tf_RefPtrTrackerUtil::Watch(obj); \
245 } \
246 inline void Tf_RefPtrTracker_LastRef(const void*, T* obj) { \
247  Tf_RefPtrTrackerUtil::Unwatch(obj); \
248 } \
249 inline void Tf_RefPtrTracker_New(const void* owner, T* obj) { \
250  Tf_RefPtrTrackerUtil::AddTrace(owner, obj); \
251 } \
252 inline void Tf_RefPtrTracker_Delete(const void* owner, T* obj) { \
253  Tf_RefPtrTrackerUtil::RemoveTraces(owner); \
254 } \
255 inline void Tf_RefPtrTracker_Assign(const void* owner, T* obj, T* oldObj) { \
256  if (oldObj != obj) { \
257  Tf_RefPtrTrackerUtil::AddTrace(owner, obj, TfRefPtrTracker::Assign);\
258  } \
259 }
260 
261 PXR_NAMESPACE_CLOSE_SCOPE
262 
263 #endif
Manage a single instance of an object.
Manage a single instance of an object (see.
Definition: singleton.h:122
std::vector< uintptr_t > trace
The stack trace when the TfRefPtr was created or assigned to.
TF_API void ReportAllWatchedCounts(std::ostream &stream) const
Writes all watched objects and the number of owners of each to stream.
TraceType type
Whether the TfRefPtr was created or assigned to.
const TfRefBase * obj
The object being pointed to.
static bool WatchNone(const void *)
Handy function to pass as second argument to TF_DEFINE_REFPTR_TRACK.
Enable a concrete base class for use with TfRefPtr.
Definition: refBase.h:71
Provides tracking of TfRefPtr objects to particular objects.
Definition: refPtrTracker.h:97
TF_API void ReportTracesForWatched(std::ostream &stream, const TfRefBase *watched) const
Writes traces for all owners of watched.
TF_API void SetStackTraceMaxDepth(size_t)
Sets the maximum stack trace depth.
static T & GetInstance()
Return a reference to an object of type T, creating it if necessary.
Definition: singleton.h:137
TfHashMap< const void *, Trace, TfHash > OwnerTraces
Maps a TfRefPtr address to the most recent trace for it.
TF_API WatchedCounts GetWatchedCounts() const
Returns the watched objects and the number of owners of each.
Reference-counted smart pointer utility class.
Definition: refBase.h:37
static bool WatchAll(const void *)
Handy function to pass as second argument to TF_DEFINE_REFPTR_TRACK.
TF_API void ReportAllTraces(std::ostream &stream) const
Writes all traces to stream.
TfHashMap< const TfRefBase *, size_t, TfHash > WatchedCounts
Maps a TfRefBase object pointer to the number of TfRefPtr objects using it.
TF_API size_t GetStackTraceMaxDepth() const
Returns the maximum stack trace depth.
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:141
TF_API OwnerTraces GetAllTraces() const
Returns traces for all owners. Returns a copy for thread safety.