00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __TBB_exception_H
00030 #define __TBB_exception_H
00031
00032 #include "tbb_stddef.h"
00033
00034 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00035
00036 #pragma warning (push)
00037 #pragma warning (disable: 4530)
00038 #endif
00039
00040 #include <stdexcept>
00041 #include <string>
00042
00043 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00044 #pragma warning (pop)
00045 #endif
00046
00047 namespace tbb {
00048
00050 class bad_last_alloc : public std::bad_alloc {
00051 public:
00052 const char* what() const throw();
00053 #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN
00054 ~bad_last_alloc() throw() {}
00055 #endif
00056 };
00057
00059 class improper_lock : public std::exception {
00060 public:
00061 const char* what() const throw();
00062 };
00063
00065 class user_abort : public std::exception {
00066 public:
00067 const char* what() const throw();
00068 };
00069
00071 class missing_wait : public std::exception {
00072 public:
00073 const char* what() const throw();
00074 };
00075
00077 class invalid_multiple_scheduling : public std::exception {
00078 public:
00079 const char* what() const throw();
00080 };
00081
00082 namespace internal {
00084 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();
00085
00086 enum exception_id {
00087 eid_bad_alloc = 1,
00088 eid_bad_last_alloc,
00089 eid_nonpositive_step,
00090 eid_out_of_range,
00091 eid_segment_range_error,
00092 eid_index_range_error,
00093 eid_missing_wait,
00094 eid_invalid_multiple_scheduling,
00095 eid_improper_lock,
00096 eid_possible_deadlock,
00097 eid_operation_not_permitted,
00098 eid_condvar_wait_failed,
00099 eid_invalid_load_factor,
00100 eid_reserved,
00101 eid_invalid_swap,
00102 eid_reservation_length_error,
00103 eid_invalid_key,
00104 eid_user_abort,
00105 eid_reserved1,
00106 #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
00107
00108
00109 eid_blocking_sch_init = eid_reserved1,
00110 #endif
00112
00114 eid_max
00115 };
00116
00118
00120 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
00121
00123 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
00124
00125 }
00126 }
00127
00128 #if __TBB_TASK_GROUP_CONTEXT
00129 #include "tbb_allocator.h"
00130 #include <exception>
00131 #include <typeinfo>
00132 #include <new>
00133
00134 namespace tbb {
00135
00137
00157 class tbb_exception : public std::exception
00158 {
00162 void* operator new ( size_t );
00163
00164 public:
00166
00167 virtual tbb_exception* move () throw() = 0;
00168
00170
00172 virtual void destroy () throw() = 0;
00173
00175
00179 virtual void throw_self () = 0;
00180
00182 virtual const char* name() const throw() = 0;
00183
00185 virtual const char* what() const throw() = 0;
00186
00193 void operator delete ( void* p ) {
00194 internal::deallocate_via_handler_v3(p);
00195 }
00196 };
00197
00199
00203 class captured_exception : public tbb_exception
00204 {
00205 public:
00206 captured_exception ( const captured_exception& src )
00207 : tbb_exception(src), my_dynamic(false)
00208 {
00209 set(src.my_exception_name, src.my_exception_info);
00210 }
00211
00212 captured_exception ( const char* name_, const char* info )
00213 : my_dynamic(false)
00214 {
00215 set(name_, info);
00216 }
00217
00218 __TBB_EXPORTED_METHOD ~captured_exception () throw();
00219
00220 captured_exception& operator= ( const captured_exception& src ) {
00221 if ( this != &src ) {
00222 clear();
00223 set(src.my_exception_name, src.my_exception_info);
00224 }
00225 return *this;
00226 }
00227
00228
00229 captured_exception* __TBB_EXPORTED_METHOD move () throw();
00230
00231
00232 void __TBB_EXPORTED_METHOD destroy () throw();
00233
00234
00235 void throw_self () { __TBB_THROW(*this); }
00236
00237
00238 const char* __TBB_EXPORTED_METHOD name() const throw();
00239
00240
00241 const char* __TBB_EXPORTED_METHOD what() const throw();
00242
00243 void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00244 void __TBB_EXPORTED_METHOD clear () throw();
00245
00246 private:
00248 captured_exception() {}
00249
00251 static captured_exception* allocate ( const char* name, const char* info );
00252
00253 bool my_dynamic;
00254 const char* my_exception_name;
00255 const char* my_exception_info;
00256 };
00257
00259
00263 template<typename ExceptionData>
00264 class movable_exception : public tbb_exception
00265 {
00266 typedef movable_exception<ExceptionData> self_type;
00267
00268 public:
00269 movable_exception ( const ExceptionData& data_ )
00270 : my_exception_data(data_)
00271 , my_dynamic(false)
00272 , my_exception_name(
00273 #if TBB_USE_EXCEPTIONS
00274 typeid(self_type).name()
00275 #else
00276 "movable_exception"
00277 #endif
00278 )
00279 {}
00280
00281 movable_exception ( const movable_exception& src ) throw ()
00282 : tbb_exception(src)
00283 , my_exception_data(src.my_exception_data)
00284 , my_dynamic(false)
00285 , my_exception_name(src.my_exception_name)
00286 {}
00287
00288 ~movable_exception () throw() {}
00289
00290 const movable_exception& operator= ( const movable_exception& src ) {
00291 if ( this != &src ) {
00292 my_exception_data = src.my_exception_data;
00293 my_exception_name = src.my_exception_name;
00294 }
00295 return *this;
00296 }
00297
00298 ExceptionData& data () throw() { return my_exception_data; }
00299
00300 const ExceptionData& data () const throw() { return my_exception_data; }
00301
00302 const char* name () const throw() { return my_exception_name; }
00303
00304 const char* what () const throw() { return "tbb::movable_exception"; }
00305
00306
00307 movable_exception* move () throw() {
00308 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00309 if ( e ) {
00310 ::new (e) movable_exception(*this);
00311 ((movable_exception*)e)->my_dynamic = true;
00312 }
00313 return (movable_exception*)e;
00314 }
00315
00316 void destroy () throw() {
00317 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00318 if ( my_dynamic ) {
00319 this->~movable_exception();
00320 internal::deallocate_via_handler_v3(this);
00321 }
00322 }
00323
00324 void throw_self () { __TBB_THROW( *this ); }
00325
00326 protected:
00328 ExceptionData my_exception_data;
00329
00330 private:
00332 bool my_dynamic;
00333
00335
00336 const char* my_exception_name;
00337 };
00338
00339 #if !TBB_USE_CAPTURED_EXCEPTION
00340 namespace internal {
00341
00343
00345 class tbb_exception_ptr {
00346 std::exception_ptr my_ptr;
00347
00348 public:
00349 static tbb_exception_ptr* allocate ();
00350 static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00352 static tbb_exception_ptr* allocate ( captured_exception& src );
00353
00355
00356 void destroy () throw();
00357
00359 void throw_self () { std::rethrow_exception(my_ptr); }
00360
00361 private:
00362 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00363 tbb_exception_ptr ( const captured_exception& src ) :
00364 #if __TBB_MAKE_EXCEPTION_PTR_PRESENT
00365 my_ptr(std::make_exception_ptr(src))
00366 #else
00367 my_ptr(std::copy_exception(src))
00368 #endif
00369 {}
00370 };
00371
00372 }
00373 #endif
00374
00375 }
00376
00377 #endif
00378
00379 #endif