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,
00097 eid_reserved1,
00098 #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
00099
00100
00101 eid_blocking_sch_init = eid_reserved1,
00102 #endif
00104
00106 eid_max
00107 };
00108
00110
00112 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
00113
00115 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
00116
00117 }
00118 }
00119
00120 #if __TBB_TASK_GROUP_CONTEXT
00121 #include "tbb_allocator.h"
00122 #include <exception>
00123 #include <typeinfo>
00124 #include <new>
00125
00126 namespace tbb {
00127
00129
00149 class tbb_exception : public std::exception
00150 {
00154 void* operator new ( size_t );
00155
00156 public:
00158
00159 virtual tbb_exception* move () throw() = 0;
00160
00162
00164 virtual void destroy () throw() = 0;
00165
00167
00171 virtual void throw_self () = 0;
00172
00174 virtual const char* name() const throw() = 0;
00175
00177 virtual const char* what() const throw() = 0;
00178
00185 void operator delete ( void* p ) {
00186 internal::deallocate_via_handler_v3(p);
00187 }
00188 };
00189
00191
00195 class captured_exception : public tbb_exception
00196 {
00197 public:
00198 captured_exception ( const captured_exception& src )
00199 : tbb_exception(src), my_dynamic(false)
00200 {
00201 set(src.my_exception_name, src.my_exception_info);
00202 }
00203
00204 captured_exception ( const char* name_, const char* info )
00205 : my_dynamic(false)
00206 {
00207 set(name_, info);
00208 }
00209
00210 __TBB_EXPORTED_METHOD ~captured_exception () throw();
00211
00212 captured_exception& operator= ( const captured_exception& src ) {
00213 if ( this != &src ) {
00214 clear();
00215 set(src.my_exception_name, src.my_exception_info);
00216 }
00217 return *this;
00218 }
00219
00220
00221 captured_exception* __TBB_EXPORTED_METHOD move () throw();
00222
00223
00224 void __TBB_EXPORTED_METHOD destroy () throw();
00225
00226
00227 void throw_self () { __TBB_THROW(*this); }
00228
00229
00230 const char* __TBB_EXPORTED_METHOD name() const throw();
00231
00232
00233 const char* __TBB_EXPORTED_METHOD what() const throw();
00234
00235 void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00236 void __TBB_EXPORTED_METHOD clear () throw();
00237
00238 private:
00240 captured_exception() {}
00241
00243 static captured_exception* allocate ( const char* name, const char* info );
00244
00245 bool my_dynamic;
00246 const char* my_exception_name;
00247 const char* my_exception_info;
00248 };
00249
00251
00255 template<typename ExceptionData>
00256 class movable_exception : public tbb_exception
00257 {
00258 typedef movable_exception<ExceptionData> self_type;
00259
00260 public:
00261 movable_exception ( const ExceptionData& data_ )
00262 : my_exception_data(data_)
00263 , my_dynamic(false)
00264 , my_exception_name(
00265 #if TBB_USE_EXCEPTIONS
00266 typeid(self_type).name()
00267 #else
00268 "movable_exception"
00269 #endif
00270 )
00271 {}
00272
00273 movable_exception ( const movable_exception& src ) throw ()
00274 : tbb_exception(src)
00275 , my_exception_data(src.my_exception_data)
00276 , my_dynamic(false)
00277 , my_exception_name(src.my_exception_name)
00278 {}
00279
00280 ~movable_exception () throw() {}
00281
00282 const movable_exception& operator= ( const movable_exception& src ) {
00283 if ( this != &src ) {
00284 my_exception_data = src.my_exception_data;
00285 my_exception_name = src.my_exception_name;
00286 }
00287 return *this;
00288 }
00289
00290 ExceptionData& data () throw() { return my_exception_data; }
00291
00292 const ExceptionData& data () const throw() { return my_exception_data; }
00293
00294 const char* name () const throw() { return my_exception_name; }
00295
00296 const char* what () const throw() { return "tbb::movable_exception"; }
00297
00298
00299 movable_exception* move () throw() {
00300 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00301 if ( e ) {
00302 ::new (e) movable_exception(*this);
00303 ((movable_exception*)e)->my_dynamic = true;
00304 }
00305 return (movable_exception*)e;
00306 }
00307
00308 void destroy () throw() {
00309 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00310 if ( my_dynamic ) {
00311 this->~movable_exception();
00312 internal::deallocate_via_handler_v3(this);
00313 }
00314 }
00315
00316 void throw_self () { __TBB_THROW( *this ); }
00317
00318 protected:
00320 ExceptionData my_exception_data;
00321
00322 private:
00324 bool my_dynamic;
00325
00327
00328 const char* my_exception_name;
00329 };
00330
00331 #if !TBB_USE_CAPTURED_EXCEPTION
00332 namespace internal {
00333
00335
00337 class tbb_exception_ptr {
00338 std::exception_ptr my_ptr;
00339
00340 public:
00341 static tbb_exception_ptr* allocate ();
00342 static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00344 static tbb_exception_ptr* allocate ( captured_exception& src );
00345
00347
00348 void destroy () throw();
00349
00351 void throw_self () { std::rethrow_exception(my_ptr); }
00352
00353 private:
00354 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00355 tbb_exception_ptr ( const captured_exception& src ) :
00356 #if __TBB_MAKE_EXCEPTION_PTR_PRESENT
00357 my_ptr(std::make_exception_ptr(src))
00358 #else
00359 my_ptr(std::copy_exception(src))
00360 #endif
00361 {}
00362 };
00363
00364 }
00365 #endif
00366
00367 }
00368
00369 #endif
00370
00371 #endif