HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
error.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 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 _GUSD_ERROR_H_
25 #define _GUSD_ERROR_H_
26 
27 #include "gusd/api.h"
28 
29 #include "pxr/pxr.h"
30 
31 #include "pxr/base/arch/hints.h"
32 #include "pxr/base/tf/errorMark.h"
33 
34 #include <UT/UT_ErrorManager.h>
35 #include <UT/UT_Lock.h>
36 #include <UT/UT_NonCopyable.h>
37 #include <UT/UT_WorkBuffer.h>
38 
39 
41 
42 
43 /// Evaluate and post an error message, based on a configurable
44 /// reporting severity.
45 ///
46 /// This macros is used as follows:
47 /// \code
48 /// GUSD_GENERIC_ERR(sev).Msg("Failed because of: %s", reason);
49 /// \endcode
50 ///
51 /// The result of the macro itself is a GusdPostErrorHelper object,
52 /// through which errors may be posted. If the severity is UT_ERROR_NONE,
53 /// none of the error-posting code will be invoked.
54 #define GUSD_GENERIC_ERR(sev) \
55  if(sev == UT_ERROR_NONE) /*empty*/ ; else GusdPostErrorHelper(sev)
56 
57 #define GUSD_ERR() GusdPostErrorHelper(UT_ERROR_ABORT)
58 
59 #define GUSD_WARN() GusdPostErrorHelper(UT_ERROR_WARNING)
60 
61 #define GUSD_MSG() GusdPostErrorHelper(UT_ERROR_MESSAGE)
62 
63 
65 {
66 public:
68 
69  void Msg(const char* msg) const;
70 
71  template <typename T, typename... Args>
72  void Msg(const char* format, T&& arg1, Args&&... args) const;
73 
74 private:
75  UT_ErrorSeverity _sev;
76 };
77 
78 
79 template <typename T, typename... Args>
80 void
81 GusdPostErrorHelper::Msg(const char* format, T&& arg1, Args&&... args) const
82 {
84  buf.sprintf(format, std::forward<T>(arg1), std::forward<Args>(args)...);
85  UTaddGeneric(_sev, "Common", UT_ERROR_JUST_STRING, buf.buffer());
86 }
87 
88 
89 /// Helper class used to propagate errors from different threads.
90 /// There is a thread-local UT_ErrorManager for each thread in Houdini.
91 /// Error reporting methods should generally just call UTaddError(),
92 /// UTaddWarning(), etc. to report errors, -- or GUSD_ERR, and similar
93 /// helpers above -- which will put errors on currently scoped UT_ErrorManager
94 /// of the active thread.
95 /// When splitting into threads, though, an additional step is required
96 /// to pull any error messages from each thread that is spawned, to copy them
97 /// back into the originating thread.
98 ///
99 /// Example:
100 /// \code
101 /// GusdErrorTransport errTransport;
102 /// UTparallelFor(
103 /// UT_BlockedRange<size_t>(0,n),
104 /// [&](const UT_BlockedRange<size_t>& r)
105 /// {
106 /// GusdAutoErrorTransport autoErrTransport(errTransport):
107 /// UTaddError(...);
108 /// ...
109 /// });
110 /// \endcode
112 {
113 public:
115 
117 
118  void operator()()
119  { StealGlobalErrors(); }
120 
121  void StealErrors(UT_ErrorManager& victim,
123  bool borrowOnly=false);
124 
126  bool borrowOnly=false)
127  { StealErrors(*UTgetErrorManager(), sev, borrowOnly); }
128 
129 private:
130  UT_Lock _lock;
131  UT_ErrorManager* const _mgr;
132 };
133 
134 
135 /// Helper for ensuring consistent, automatic transport of errors from
136 /// within threaded loops. This avoids the need for HextUT_ErrorTransport
137 /// users to manually trigger error transport when returning from a
138 /// threaded call.
140 {
141 public:
143  : _transport(transport) {}
144 
145  ~GusdAutoErrorTransport() { _transport(); }
146 
147 private:
148  GusdErrorTransport& _transport;
149 };
150 
151 
152 /// Helper for extracting error messages from \p mgr.
153 /// Any errors with a severity greater or equal to \p sev are included.
157 
158 
159 /// Helper for catching Tf errors and forwarding them to a UT_ErrorManager.
160 /// Note that it's currently only possible to forward a subset of Tf errors.
161 /// Warnings and status messages cannot be forwarded.
163 {
164 public:
165  /// Construct a scope for capturing Tf errors and forwarding them to \p mgr.
166  /// Captured Tf errors are forwarding to \p mgr with a severity of \p sev.
167  /// If \p sev is UT_ERROR_NONE, the Tf errors will be silently ignored.
170  : _mgr(mgr), _sev(sev)
171  { _mark.SetMark(); }
172 
174  {
175  if(ARCH_UNLIKELY(!_mark.IsClean()))
176  _Update();
177  }
178 
179  explicit operator bool() const { return _mgr; }
180 
181  /// Clean any errors on the current scope.
182  /// Returns the resulting error level.
184  {
185  if(_mark.IsClean())
186  return UT_ERROR_NONE;
187  return _Update();
188  }
189 
190  bool IsClean() const { return _mark.IsClean(); }
191 
192  UT_ErrorSeverity GetLogSeverity() const { return _sev; }
193 
194 protected:
195  UT_ErrorSeverity _Update();
196 
197 private:
198  TfErrorMark _mark;
199  UT_ErrorManager* const _mgr;
200  const UT_ErrorSeverity _sev;
201 };
202 
203 
205 
206 #endif // _GUSD_ERROR_H_
SYS_FORCE_INLINE const char * buffer() const
UT_ErrorSeverity
Definition: UT_Error.h:25
UT_API UT_ErrorManager * UTgetErrorManager()
void operator()()
Definition: error.h:118
void StealGlobalErrors(UT_ErrorSeverity sev=UT_ERROR_NONE, bool borrowOnly=false)
Definition: error.h:125
Definition: error.h:64
GusdAutoErrorTransport(GusdErrorTransport &transport)
Definition: error.h:142
#define ARCH_UNLIKELY(x)
Definition: hints.h:47
UT_ErrorSeverity GetLogSeverity() const
Definition: error.h:192
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
GusdPostErrorHelper(UT_ErrorSeverity sev)
Definition: error.h:67
~GusdTfErrorScope()
Definition: error.h:173
UT_ErrorSeverity Update()
Definition: error.h:183
void Msg(const char *msg) const
int sprintf(const char *fmt,...) SYS_PRINTF_CHECK_ATTRIBUTE(2
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:107
**Note that the tasks the is the thread number *for the or if it s being executed by a non pool thread(this *can happen in cases where the whole pool is occupied and the calling *thread contributes to running the work load).**Thread pool.Have fun
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1375
GUSD_API std::string GusdGetErrors(UT_ErrorManager *mgr=UTgetErrorManager(), UT_ErrorSeverity sev=UT_ERROR_NONE)
GusdErrorTransport(int thread)
Definition: error.h:116
GLuint GLuint GLuint arg1
Definition: glew.h:8295
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
A global error manager scope.
**If you just want to fire and args
Definition: thread.h:615
#define GUSD_API
Definition: api.h:40
GusdTfErrorScope(UT_ErrorSeverity sev=UT_ERROR_ABORT, UT_ErrorManager *mgr=UTgetErrorManager())
Definition: error.h:168
GusdErrorTransport(UT_ErrorManager *mgr=UTgetErrorManager())
Definition: error.h:114
UT_API UT_ErrorSeverity UTaddGeneric(UT_ErrorSeverity sev, const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0)
Add a generic error message to the global error manager.
bool IsClean() const
Definition: error.h:190