BRE12
tbb_exception.h
1 /*
2  Copyright 2005-2016 Intel Corporation. All Rights Reserved.
3 
4  This file is part of Threading Building Blocks. Threading Building Blocks is free software;
5  you can redistribute it and/or modify it under the terms of the GNU General Public License
6  version 2 as published by the Free Software Foundation. Threading Building Blocks is
7  distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  See the GNU General Public License for more details. You should have received a copy of
10  the GNU General Public License along with Threading Building Blocks; if not, write to the
11  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12 
13  As a special exception, you may use this file as part of a free software library without
14  restriction. Specifically, if other files instantiate templates or use macros or inline
15  functions from this file, or you compile this file and link it with other files to produce
16  an executable, this file does not by itself cause the resulting executable to be covered
17  by the GNU General Public License. This exception does not however invalidate any other
18  reasons why the executable file might be covered by the GNU General Public License.
19 */
20 
21 #ifndef __TBB_exception_H
22 #define __TBB_exception_H
23 
24 #include "tbb_stddef.h"
25 
26 #if !TBB_USE_EXCEPTIONS && _MSC_VER
27  // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
28  #pragma warning (push)
29  #pragma warning (disable: 4530)
30 #endif
31 
32 #include <exception>
33 #include <new> //required for bad_alloc definition, operators new
34 #include <string> // required to construct std exception classes
35 
36 #if !TBB_USE_EXCEPTIONS && _MSC_VER
37  #pragma warning (pop)
38 #endif
39 
40 namespace tbb {
41 
43 class bad_last_alloc : public std::bad_alloc {
44 public:
45  /*override*/ const char* what() const throw();
46 #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN
47  /*override*/ ~bad_last_alloc() throw() {}
48 #endif
49 };
50 
52 class improper_lock : public std::exception {
53 public:
54  /*override*/ const char* what() const throw();
55 };
56 
58 class user_abort : public std::exception {
59 public:
60  /*override*/ const char* what() const throw();
61 };
62 
64 class missing_wait : public std::exception {
65 public:
66  /*override*/ const char* what() const throw();
67 };
68 
70 class invalid_multiple_scheduling : public std::exception {
71 public:
72  /*override*/ const char* what() const throw();
73 };
74 
75 namespace internal {
77 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();
78 
79 enum exception_id {
80  eid_bad_alloc = 1,
81  eid_bad_last_alloc,
82  eid_nonpositive_step,
83  eid_out_of_range,
84  eid_segment_range_error,
85  eid_index_range_error,
86  eid_missing_wait,
87  eid_invalid_multiple_scheduling,
88  eid_improper_lock,
89  eid_possible_deadlock,
90  eid_operation_not_permitted,
91  eid_condvar_wait_failed,
92  eid_invalid_load_factor,
93  eid_reserved, // free slot for backward compatibility, can be reused.
94  eid_invalid_swap,
95  eid_reservation_length_error,
96  eid_invalid_key,
97  eid_user_abort,
98  eid_reserved1,
99 #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
100  // This id is used only inside library and only for support of CPF functionality.
101  // So, if we drop the functionality, eid_reserved1 can be safely renamed and reused.
102  eid_blocking_sch_init = eid_reserved1,
103 #endif
104  eid_bad_tagged_msg_cast,
106 
108  eid_max
109 };
110 
112 
114 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
115 
117 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
118 
119 } // namespace internal
120 } // namespace tbb
121 
122 #if __TBB_TASK_GROUP_CONTEXT
123 #include "tbb_allocator.h"
124 #include <typeinfo> //for typeid
125 
126 namespace tbb {
127 
129 
149 class tbb_exception : public std::exception
150 {
154  void* operator new ( size_t );
155 
156 public:
157 #if __clang__
158  // At -O3 or even -O2 optimization level, Clang may fully throw away an empty destructor
159  // of tbb_exception from destructors of derived classes. As a result, it does not create
160  // vtable for tbb_exception, which is a required part of TBB binary interface.
161  // Making the destructor non-empty (with just a semicolon) prevents that optimization.
162  ~tbb_exception() throw() { /* keep the semicolon! */ ; }
163 #endif
164 
166 
167  virtual tbb_exception* move () throw() = 0;
168 
170 
172  virtual void destroy () throw() = 0;
173 
175 
179  virtual void throw_self () = 0;
180 
182  virtual const char* name() const throw() = 0;
183 
185  virtual const char* what() const throw() = 0;
186 
193  void operator delete ( void* p ) {
194  internal::deallocate_via_handler_v3(p);
195  }
196 };
197 
199 
204 {
205 public:
207  : tbb_exception(src), my_dynamic(false)
208  {
209  set(src.my_exception_name, src.my_exception_info);
210  }
211 
212  captured_exception ( const char* name_, const char* info )
213  : my_dynamic(false)
214  {
215  set(name_, info);
216  }
217 
218  __TBB_EXPORTED_METHOD ~captured_exception () throw();
219 
220  captured_exception& operator= ( const captured_exception& src ) {
221  if ( this != &src ) {
222  clear();
223  set(src.my_exception_name, src.my_exception_info);
224  }
225  return *this;
226  }
227 
228  /*override*/
229  captured_exception* __TBB_EXPORTED_METHOD move () throw();
230 
231  /*override*/
232  void __TBB_EXPORTED_METHOD destroy () throw();
233 
234  /*override*/
235  void throw_self () { __TBB_THROW(*this); }
236 
237  /*override*/
238  const char* __TBB_EXPORTED_METHOD name() const throw();
239 
240  /*override*/
241  const char* __TBB_EXPORTED_METHOD what() const throw();
242 
243  void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
244  void __TBB_EXPORTED_METHOD clear () throw();
245 
246 private:
248  captured_exception() {}
249 
251  static captured_exception* allocate ( const char* name, const char* info );
252 
253  bool my_dynamic;
254  const char* my_exception_name;
255  const char* my_exception_info;
256 };
257 
259 
263 template<typename ExceptionData>
265 {
267 
268 public:
269  movable_exception ( const ExceptionData& data_ )
270  : my_exception_data(data_)
271  , my_dynamic(false)
272  , my_exception_name(
273 #if TBB_USE_EXCEPTIONS
274  typeid(self_type).name()
275 #else /* !TBB_USE_EXCEPTIONS */
276  "movable_exception"
277 #endif /* !TBB_USE_EXCEPTIONS */
278  )
279  {}
280 
281  movable_exception ( const movable_exception& src ) throw ()
282  : tbb_exception(src)
283  , my_exception_data(src.my_exception_data)
284  , my_dynamic(false)
285  , my_exception_name(src.my_exception_name)
286  {}
287 
288  ~movable_exception () throw() {}
289 
290  const movable_exception& operator= ( const movable_exception& src ) {
291  if ( this != &src ) {
292  my_exception_data = src.my_exception_data;
293  my_exception_name = src.my_exception_name;
294  }
295  return *this;
296  }
297 
298  ExceptionData& data () throw() { return my_exception_data; }
299 
300  const ExceptionData& data () const throw() { return my_exception_data; }
301 
302  /*override*/ const char* name () const throw() { return my_exception_name; }
303 
304  /*override*/ const char* what () const throw() { return "tbb::movable_exception"; }
305 
306  /*override*/
307  movable_exception* move () throw() {
308  void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
309  if ( e ) {
310  ::new (e) movable_exception(*this);
311  ((movable_exception*)e)->my_dynamic = true;
312  }
313  return (movable_exception*)e;
314  }
315  /*override*/
316  void destroy () throw() {
317  __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
318  if ( my_dynamic ) {
319  this->~movable_exception();
320  internal::deallocate_via_handler_v3(this);
321  }
322  }
323  /*override*/
324  void throw_self () { __TBB_THROW( *this ); }
325 
326 protected:
328  ExceptionData my_exception_data;
329 
330 private:
332  bool my_dynamic;
333 
335 
336  const char* my_exception_name;
337 };
338 
339 #if !TBB_USE_CAPTURED_EXCEPTION
340 namespace internal {
341 
343 
345 class tbb_exception_ptr {
346  std::exception_ptr my_ptr;
347 
348 public:
349  static tbb_exception_ptr* allocate ();
350  static tbb_exception_ptr* allocate ( const tbb_exception& tag );
352  static tbb_exception_ptr* allocate ( captured_exception& src );
353 
355 
356  void destroy () throw();
357 
359  void throw_self () { std::rethrow_exception(my_ptr); }
360 
361 private:
362  tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
363  tbb_exception_ptr ( const captured_exception& src ) :
364  #if __TBB_MAKE_EXCEPTION_PTR_PRESENT
365  my_ptr(std::make_exception_ptr(src)) // the final function name in C++11
366  #else
367  my_ptr(std::copy_exception(src)) // early C++0x drafts name
368  #endif
369  {}
370 }; // class tbb::internal::tbb_exception_ptr
371 
372 } // namespace internal
373 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
374 
375 } // namespace tbb
376 
377 #endif /* __TBB_TASK_GROUP_CONTEXT */
378 
379 #endif /* __TBB_exception_H */
Exception for PPL locks.
Definition: tbb_exception.h:52
This class is used by TBB to propagate information about unhandled exceptions into the root thread...
Definition: tbb_exception.h:203
Interface to be implemented by all exceptions TBB recognizes and propagates across the threads...
Definition: tbb_exception.h:149
movable_exception * move()
Creates and returns pointer to the deep copy of this exception object.
Definition: tbb_exception.h:307
Exception for concurrent containers.
Definition: tbb_exception.h:43
Exception for repeated scheduling of the same task_handle.
Definition: tbb_exception.h:70
Template that can be used to implement exception that transfers arbitrary ExceptionData to the root t...
Definition: tbb_exception.h:264
const char * what() const
Returns the result of originally intercepted exception&#39;s what() method.
Definition: tbb_exception.h:304
const char * name() const
Returns RTTI name of the originally intercepted exception.
Definition: tbb_exception.h:302
*/
Definition: material.h:665
Definition: _flow_graph_async_msg_impl.h:32
void throw_self()
Throws this exception object.
Definition: tbb_exception.h:235
Exception for user-initiated abort.
Definition: tbb_exception.h:58
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44
void destroy()
Destroys objects created by the move() method.
Definition: tbb_exception.h:316
ExceptionData my_exception_data
User data.
Definition: tbb_exception.h:328
Exception for missing wait on structured_task_group.
Definition: tbb_exception.h:64
void throw_self()
Throws this exception object.
Definition: tbb_exception.h:324