HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
errorMark.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_ERROR_MARK_H
25 #define PXR_BASE_TF_ERROR_MARK_H
26 
27 /// \file tf/errorMark.h
28 
29 #include "pxr/pxr.h"
32 #include "pxr/base/tf/api.h"
33 
34 #include <hboost/noncopyable.hpp>
35 
37 
38 /// \class TfErrorMark
39 /// \ingroup group_tf_TfError
40 ///
41 /// Class used to record the end of the error-list.
42 ///
43 /// See \ref page_tf_TfError for a detailed description.
44 ///
45 /// A \c TfErrorMark is used as follows:
46 /// \code
47 /// TfErrorMark m;
48 ///
49 /// m.SetMark(); // (A)
50 /// ... ;
51 /// ... ;
52 /// // (B)
53 /// if (!m.IsClean()) {
54 /// // errors occurred between (A) and (B)
55 /// }
56 /// \endcode
57 ///
58 /// Another common pattern is
59 /// \code
60 /// TfErrorMark m;
61 /// if (TF_HAS_ERRORS(m, expr)) {
62 /// // handle errors;
63 /// }
64 /// \endcode
65 ///
66 class TfErrorMark : hboost::noncopyable
67 {
68  public:
69 
71 
72  /// Default constructor.
73  ///
74  /// The default constructor automatically calls \c SetMark() at the point
75  /// of declaration.
77 
78  /// Destroy this ErrorMark.
79  ///
80  /// If this is the last ErrorMark on this thread of execution and there
81  /// are pending errors, this will report them via the diagnostic delegate
82  /// (if one is installed) otherwise by printing to stderr.
84 
85  /// Record future errors.
86  ///
87  /// \c SetMark() arranges to record future errors in \c *this.
88  inline void SetMark() {
89  _mark = TfDiagnosticMgr::GetInstance()._nextSerial;
90  }
91 
92  /// Return true if no new errors were posted in this thread since the last
93  /// call to \c SetMark(), false otherwise.
94  ///
95  /// When no threads are issuing errors the cost of this function is an
96  /// atomic integer read and comparison. Otherwise thread-specific data is
97  /// accessed to make the determination. Thus, this function is fast when
98  /// diagnostics are not being issued.
99  inline bool IsClean() const {
101  return _mark >= mgr._nextSerial || _IsCleanImpl(mgr);
102  }
103 
104  /// Remove all errors in this mark from the error system. Return true if
105  /// any errors were cleared, false if there were no errors in this mark.
106  ///
107  /// Clear all errors contained in this mark from the error system.
108  /// Subsequently, these errors will be considered handled.
109  inline bool Clear() const {
111  auto b = GetBegin(), e = mgr.GetErrorEnd();
112  if (b != e) {
113  mgr.EraseRange(b, e);
114  return true;
115  }
116  return false;
117  }
118 
119  /// Remove all errors in this mark fom the error system and return them in
120  /// a TfErrorTransport.
121  ///
122  /// This can be used to transfer errors from one thread to another. See
123  /// TfErrorTransport for more information. As with Clear(), all the
124  /// removed errors are considered handled for this thread. See also
125  /// TransportTo().
126  inline TfErrorTransport Transport() const {
128  return TfErrorTransport(mgr._errorList.local(),
129  GetBegin(), mgr.GetErrorEnd());
130  }
131 
132  /// Remove all errors in this mark fom the error system and return them in
133  /// a TfErrorTransport.
134  ///
135  /// This is a variant of Transport(). Instead of returning a new
136  /// TfErrorTransport object it fills an existing one.
137  inline void TransportTo(TfErrorTransport &dest) const {
138  Transport().swap(dest);
139  }
140 
141  /// Return an iterator to the first error added to the error list after
142  /// \c SetMark().
143  ///
144  /// If there are no errors on the error list that were not already present
145  /// when \c SetMark() was called, the iterator returned is equal to the
146  /// iterator returned by \c TfDiagnosticMgr::GetErrorEnd(). Otherwise, the
147  /// iterator points to the earliest error added to the list since
148  /// \c SetMark() was called.
149  ///
150  /// This function takes O(n) time where n is the number of errors from the
151  /// end of the list to the mark i.e. \c GetMark() walks the list from the
152  /// end until it finds the mark and then returns an iterator to that spot.
153  ///
154  /// If \c nErrors is non-NULL, then \c *nErrors is set to the number of
155  /// errors between the returned iterator and the end of the list.
156  Iterator GetBegin(size_t *nErrors = 0) const {
157  return
158  TfDiagnosticMgr::GetInstance()._GetErrorMarkBegin(_mark, nErrors);
159  }
160 
161  /// Return an iterator past the last error in the error system.
162  ///
163  /// This iterator is always equivalent to the iterator returned by \c
164  /// TfDiagnosticMgr::GetErrorEnd().
165  Iterator GetEnd() const {
167  }
168 
169  /// Equivalent to GetBegin()
170  Iterator begin() const { return GetBegin(); }
171 
172  /// Equivalent to GetEnd()
173  Iterator end() const { return GetEnd(); }
174 
175  private:
176  friend class TfDiagnosticMgr;
177 
178  // Helper to check if the _mark identifies any errors present on the
179  // thread-local error list.
180  TF_API bool _IsCleanImpl(TfDiagnosticMgr &mgr) const;
181 
182  void _ReportErrors(TfDiagnosticMgr &mgr) const;
183 
184  size_t _mark;
185 };
186 
187 
188 /// Convenience macro to check if errors occurred.
189 ///
190 /// This macro is equivalent to
191 /// \code
192 /// (marker.SetMark(), (expr), !marker.IsClean())
193 /// \endcode
194 ///
195 /// which enables it to be used as an expression:
196 /// \code
197 /// if (TF_HAS_ERRORS(m, expr))
198 /// // cope!
199 /// \endcode
200 ///
201 /// \ingroup group_tf_TfError
202 /// \hideinitializer
203 #define TF_HAS_ERRORS(marker, expr) \
204  (marker.SetMark(), (expr), !marker.IsClean())
205 
206 /// Report current TfErrorMark instances and the stack traces that created
207 /// them to stdout for debugging purposes.
208 ///
209 /// To call this function, set _enableTfErrorMarkStackTraces in errorMark.cpp
210 /// and enable the TF_ERROR_MARK_TRACKING TfDebug code.
211 ///
212 /// \ingroup group_tf_TfError
213 TF_API
215 
217 
218 #endif // PXR_BASE_TF_ERROR_MARK_H
#define TF_API
Definition: api.h:40
TF_API ErrorIterator EraseRange(ErrorIterator first, ErrorIterator last)
void swap(TfErrorTransport &other)
Iterator end() const
Equivalent to GetEnd()
Definition: errorMark.h:173
ErrorList::iterator ErrorIterator
Definition: diagnosticMgr.h:96
static TF_API This & GetInstance()
Return the singleton instance.
TF_API void TfReportActiveErrorMarks()
Iterator GetBegin(size_t *nErrors=0) const
Definition: errorMark.h:156
TF_API ~TfErrorMark()
TfErrorTransport Transport() const
Definition: errorMark.h:126
TfDiagnosticMgr::ErrorIterator Iterator
Definition: errorMark.h:70
Iterator GetEnd() const
Definition: errorMark.h:165
bool Clear() const
Definition: errorMark.h:109
bool IsClean() const
Definition: errorMark.h:99
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
void SetMark()
Definition: errorMark.h:88
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
void TransportTo(TfErrorTransport &dest) const
Definition: errorMark.h:137
TF_API TfErrorMark()
ErrorIterator GetErrorEnd()
Return an iterator to the end of this thread's error list.
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
Iterator begin() const
Equivalent to GetBegin()
Definition: errorMark.h:170