00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_exception_H
00022 #define __TBB_exception_H
00023
00024 #include "tbb_stddef.h"
00025
00026 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00027
00028 #pragma warning (push)
00029 #pragma warning (disable: 4530)
00030 #endif
00031
00032 #include <stdexcept>
00033 #include <string>
00034
00035 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00036 #pragma warning (pop)
00037 #endif
00038
00039 namespace tbb {
00040
00042 class bad_last_alloc : public std::bad_alloc {
00043 public:
00044 const char* what() const throw();
00045 #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN
00046 ~bad_last_alloc() throw() {}
00047 #endif
00048 };
00049
00051 class improper_lock : public std::exception {
00052 public:
00053 const char* what() const throw();
00054 };
00055
00057 class user_abort : public std::exception {
00058 public:
00059 const char* what() const throw();
00060 };
00061
00063 class missing_wait : public std::exception {
00064 public:
00065 const char* what() const throw();
00066 };
00067
00069 class invalid_multiple_scheduling : public std::exception {
00070 public:
00071 const char* what() const throw();
00072 };
00073
00074 namespace internal {
00076 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();
00077
00078 enum exception_id {
00079 eid_bad_alloc = 1,
00080 eid_bad_last_alloc,
00081 eid_nonpositive_step,
00082 eid_out_of_range,
00083 eid_segment_range_error,
00084 eid_index_range_error,
00085 eid_missing_wait,
00086 eid_invalid_multiple_scheduling,
00087 eid_improper_lock,
00088 eid_possible_deadlock,
00089 eid_operation_not_permitted,
00090 eid_condvar_wait_failed,
00091 eid_invalid_load_factor,
00092 eid_reserved,
00093 eid_invalid_swap,
00094 eid_reservation_length_error,
00095 eid_invalid_key,
00096 eid_user_abort,
00098
00100 eid_max
00101 };
00102
00104
00106 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
00107
00109 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
00110
00111 }
00112 }
00113
00114 #if __TBB_TASK_GROUP_CONTEXT
00115 #include "tbb_allocator.h"
00116 #include <exception>
00117 #include <typeinfo>
00118 #include <new>
00119
00120 namespace tbb {
00121
00123
00143 class tbb_exception : public std::exception
00144 {
00148 void* operator new ( size_t );
00149
00150 public:
00152
00153 virtual tbb_exception* move () throw() = 0;
00154
00156
00158 virtual void destroy () throw() = 0;
00159
00161
00165 virtual void throw_self () = 0;
00166
00168 virtual const char* name() const throw() = 0;
00169
00171 virtual const char* what() const throw() = 0;
00172
00179 void operator delete ( void* p ) {
00180 internal::deallocate_via_handler_v3(p);
00181 }
00182 };
00183
00185
00189 class captured_exception : public tbb_exception
00190 {
00191 public:
00192 captured_exception ( const captured_exception& src )
00193 : tbb_exception(src), my_dynamic(false)
00194 {
00195 set(src.my_exception_name, src.my_exception_info);
00196 }
00197
00198 captured_exception ( const char* name_, const char* info )
00199 : my_dynamic(false)
00200 {
00201 set(name_, info);
00202 }
00203
00204 __TBB_EXPORTED_METHOD ~captured_exception () throw();
00205
00206 captured_exception& operator= ( const captured_exception& src ) {
00207 if ( this != &src ) {
00208 clear();
00209 set(src.my_exception_name, src.my_exception_info);
00210 }
00211 return *this;
00212 }
00213
00214
00215 captured_exception* __TBB_EXPORTED_METHOD move () throw();
00216
00217
00218 void __TBB_EXPORTED_METHOD destroy () throw();
00219
00220
00221 void throw_self () { __TBB_THROW(*this); }
00222
00223
00224 const char* __TBB_EXPORTED_METHOD name() const throw();
00225
00226
00227 const char* __TBB_EXPORTED_METHOD what() const throw();
00228
00229 void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00230 void __TBB_EXPORTED_METHOD clear () throw();
00231
00232 private:
00234 captured_exception() {}
00235
00237 static captured_exception* allocate ( const char* name, const char* info );
00238
00239 bool my_dynamic;
00240 const char* my_exception_name;
00241 const char* my_exception_info;
00242 };
00243
00245
00249 template<typename ExceptionData>
00250 class movable_exception : public tbb_exception
00251 {
00252 typedef movable_exception<ExceptionData> self_type;
00253
00254 public:
00255 movable_exception ( const ExceptionData& data_ )
00256 : my_exception_data(data_)
00257 , my_dynamic(false)
00258 , my_exception_name(
00259 #if TBB_USE_EXCEPTIONS
00260 typeid(self_type).name()
00261 #else
00262 "movable_exception"
00263 #endif
00264 )
00265 {}
00266
00267 movable_exception ( const movable_exception& src ) throw ()
00268 : tbb_exception(src)
00269 , my_exception_data(src.my_exception_data)
00270 , my_dynamic(false)
00271 , my_exception_name(src.my_exception_name)
00272 {}
00273
00274 ~movable_exception () throw() {}
00275
00276 const movable_exception& operator= ( const movable_exception& src ) {
00277 if ( this != &src ) {
00278 my_exception_data = src.my_exception_data;
00279 my_exception_name = src.my_exception_name;
00280 }
00281 return *this;
00282 }
00283
00284 ExceptionData& data () throw() { return my_exception_data; }
00285
00286 const ExceptionData& data () const throw() { return my_exception_data; }
00287
00288 const char* name () const throw() { return my_exception_name; }
00289
00290 const char* what () const throw() { return "tbb::movable_exception"; }
00291
00292
00293 movable_exception* move () throw() {
00294 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00295 if ( e ) {
00296 ::new (e) movable_exception(*this);
00297 ((movable_exception*)e)->my_dynamic = true;
00298 }
00299 return (movable_exception*)e;
00300 }
00301
00302 void destroy () throw() {
00303 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00304 if ( my_dynamic ) {
00305 this->~movable_exception();
00306 internal::deallocate_via_handler_v3(this);
00307 }
00308 }
00309
00310 void throw_self () { __TBB_THROW( *this ); }
00311
00312 protected:
00314 ExceptionData my_exception_data;
00315
00316 private:
00318 bool my_dynamic;
00319
00321
00322 const char* my_exception_name;
00323 };
00324
00325 #if !TBB_USE_CAPTURED_EXCEPTION
00326 namespace internal {
00327
00329
00331 class tbb_exception_ptr {
00332 std::exception_ptr my_ptr;
00333
00334 public:
00335 static tbb_exception_ptr* allocate ();
00336 static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00338 static tbb_exception_ptr* allocate ( captured_exception& src );
00339
00341
00342 void destroy () throw();
00343
00345 void throw_self () { std::rethrow_exception(my_ptr); }
00346
00347 private:
00348 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00349 tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
00350 };
00351
00352 }
00353 #endif
00354
00355 }
00356
00357 #endif
00358
00359 #endif