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 missing_wait : public std::exception {
00058 public:
00059 const char* what() const throw();
00060 };
00061
00063 class invalid_multiple_scheduling : public std::exception {
00064 public:
00065 const char* what() const throw();
00066 };
00067
00068 namespace internal {
00070 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();
00071
00072 enum exception_id {
00073 eid_bad_alloc = 1,
00074 eid_bad_last_alloc,
00075 eid_nonpositive_step,
00076 eid_out_of_range,
00077 eid_segment_range_error,
00078 eid_index_range_error,
00079 eid_missing_wait,
00080 eid_invalid_multiple_scheduling,
00081 eid_improper_lock,
00082 eid_possible_deadlock,
00083 eid_operation_not_permitted,
00084 eid_condvar_wait_failed,
00085 eid_invalid_load_factor,
00086 eid_reserved,
00087 eid_invalid_swap,
00088 eid_reservation_length_error,
00089 eid_invalid_key,
00091
00093 eid_max
00094 };
00095
00097
00099 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
00100
00102 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
00103
00104 }
00105 }
00106
00107 #if __TBB_TASK_GROUP_CONTEXT
00108 #include "tbb_allocator.h"
00109 #include <exception>
00110 #include <typeinfo>
00111 #include <new>
00112
00113 namespace tbb {
00114
00116
00136 class tbb_exception : public std::exception
00137 {
00141 void* operator new ( size_t );
00142
00143 public:
00145
00146 virtual tbb_exception* move () throw() = 0;
00147
00149
00151 virtual void destroy () throw() = 0;
00152
00154
00158 virtual void throw_self () = 0;
00159
00161 virtual const char* name() const throw() = 0;
00162
00164 virtual const char* what() const throw() = 0;
00165
00172 void operator delete ( void* p ) {
00173 internal::deallocate_via_handler_v3(p);
00174 }
00175 };
00176
00178
00182 class captured_exception : public tbb_exception
00183 {
00184 public:
00185 captured_exception ( const captured_exception& src )
00186 : tbb_exception(src), my_dynamic(false)
00187 {
00188 set(src.my_exception_name, src.my_exception_info);
00189 }
00190
00191 captured_exception ( const char* name_, const char* info )
00192 : my_dynamic(false)
00193 {
00194 set(name_, info);
00195 }
00196
00197 __TBB_EXPORTED_METHOD ~captured_exception () throw();
00198
00199 captured_exception& operator= ( const captured_exception& src ) {
00200 if ( this != &src ) {
00201 clear();
00202 set(src.my_exception_name, src.my_exception_info);
00203 }
00204 return *this;
00205 }
00206
00207
00208 captured_exception* __TBB_EXPORTED_METHOD move () throw();
00209
00210
00211 void __TBB_EXPORTED_METHOD destroy () throw();
00212
00213
00214 void throw_self () { __TBB_THROW(*this); }
00215
00216
00217 const char* __TBB_EXPORTED_METHOD name() const throw();
00218
00219
00220 const char* __TBB_EXPORTED_METHOD what() const throw();
00221
00222 void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00223 void __TBB_EXPORTED_METHOD clear () throw();
00224
00225 private:
00227 captured_exception() {}
00228
00230 static captured_exception* allocate ( const char* name, const char* info );
00231
00232 bool my_dynamic;
00233 const char* my_exception_name;
00234 const char* my_exception_info;
00235 };
00236
00238
00242 template<typename ExceptionData>
00243 class movable_exception : public tbb_exception
00244 {
00245 typedef movable_exception<ExceptionData> self_type;
00246
00247 public:
00248 movable_exception ( const ExceptionData& data_ )
00249 : my_exception_data(data_)
00250 , my_dynamic(false)
00251 , my_exception_name(
00252 #if TBB_USE_EXCEPTIONS
00253 typeid(self_type).name()
00254 #else
00255 "movable_exception"
00256 #endif
00257 )
00258 {}
00259
00260 movable_exception ( const movable_exception& src ) throw ()
00261 : tbb_exception(src)
00262 , my_exception_data(src.my_exception_data)
00263 , my_dynamic(false)
00264 , my_exception_name(src.my_exception_name)
00265 {}
00266
00267 ~movable_exception () throw() {}
00268
00269 const movable_exception& operator= ( const movable_exception& src ) {
00270 if ( this != &src ) {
00271 my_exception_data = src.my_exception_data;
00272 my_exception_name = src.my_exception_name;
00273 }
00274 return *this;
00275 }
00276
00277 ExceptionData& data () throw() { return my_exception_data; }
00278
00279 const ExceptionData& data () const throw() { return my_exception_data; }
00280
00281 const char* name () const throw() { return my_exception_name; }
00282
00283 const char* what () const throw() { return "tbb::movable_exception"; }
00284
00285
00286 movable_exception* move () throw() {
00287 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00288 if ( e ) {
00289 ::new (e) movable_exception(*this);
00290 ((movable_exception*)e)->my_dynamic = true;
00291 }
00292 return (movable_exception*)e;
00293 }
00294
00295 void destroy () throw() {
00296 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00297 if ( my_dynamic ) {
00298 this->~movable_exception();
00299 internal::deallocate_via_handler_v3(this);
00300 }
00301 }
00302
00303 void throw_self () { __TBB_THROW( *this ); }
00304
00305 protected:
00307 ExceptionData my_exception_data;
00308
00309 private:
00311 bool my_dynamic;
00312
00314
00315 const char* my_exception_name;
00316 };
00317
00318 #if !TBB_USE_CAPTURED_EXCEPTION
00319 namespace internal {
00320
00322
00324 class tbb_exception_ptr {
00325 std::exception_ptr my_ptr;
00326
00327 public:
00328 static tbb_exception_ptr* allocate ();
00329 static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00331 static tbb_exception_ptr* allocate ( captured_exception& src );
00332
00334
00335 void destroy () throw();
00336
00338 void throw_self () { std::rethrow_exception(my_ptr); }
00339
00340 private:
00341 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00342 tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
00343 };
00344
00345 }
00346 #endif
00347
00348 }
00349
00350 #endif
00351
00352 #endif