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
00034 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00035 #pragma warning (pop)
00036 #endif
00037
00038 #if __SUNPRO_CC
00039 #include <string>
00040 #endif
00041
00042 namespace tbb {
00043
00045 class bad_last_alloc : public std::bad_alloc {
00046 public:
00047 const char* what() const throw();
00048 #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN
00049 ~bad_last_alloc() throw() {}
00050 #endif
00051 };
00052
00054 class improper_lock : public std::exception {
00055 public:
00056 const char* what() const throw();
00057 };
00058
00060 class missing_wait : public std::exception {
00061 public:
00062 const char* what() const throw();
00063 };
00064
00066 class invalid_multiple_scheduling : public std::exception {
00067 public:
00068 const char* what() const throw();
00069 };
00070
00071 namespace internal {
00073 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();
00074
00075 enum exception_id {
00076 eid_bad_alloc = 1,
00077 eid_bad_last_alloc,
00078 eid_nonpositive_step,
00079 eid_out_of_range,
00080 eid_segment_range_error,
00081 eid_index_range_error,
00082 eid_missing_wait,
00083 eid_invalid_multiple_scheduling,
00084 eid_improper_lock,
00085 eid_possible_deadlock,
00086 eid_operation_not_permitted,
00087 eid_condvar_wait_failed,
00088 eid_invalid_load_factor,
00089 eid_invalid_buckets_number,
00090 eid_invalid_swap,
00091 eid_reservation_length_error,
00092 eid_invalid_key,
00094
00096 eid_max
00097 };
00098
00100
00102 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
00103
00105 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
00106
00107 }
00108 }
00109
00110 #if __TBB_TASK_GROUP_CONTEXT
00111 #include "tbb_allocator.h"
00112 #include <exception>
00113 #include <typeinfo>
00114 #include <new>
00115
00116 namespace tbb {
00117
00119
00139 class tbb_exception : public std::exception
00140 {
00144 void* operator new ( size_t );
00145
00146 public:
00148
00149 virtual tbb_exception* move () throw() = 0;
00150
00152
00154 virtual void destroy () throw() = 0;
00155
00157
00161 virtual void throw_self () = 0;
00162
00164 virtual const char* name() const throw() = 0;
00165
00167 virtual const char* what() const throw() = 0;
00168
00175 void operator delete ( void* p ) {
00176 internal::deallocate_via_handler_v3(p);
00177 }
00178 };
00179
00181
00185 class captured_exception : public tbb_exception
00186 {
00187 public:
00188 captured_exception ( const captured_exception& src )
00189 : tbb_exception(src), my_dynamic(false)
00190 {
00191 set(src.my_exception_name, src.my_exception_info);
00192 }
00193
00194 captured_exception ( const char* name_, const char* info )
00195 : my_dynamic(false)
00196 {
00197 set(name_, info);
00198 }
00199
00200 __TBB_EXPORTED_METHOD ~captured_exception () throw() {
00201 clear();
00202 }
00203
00204 captured_exception& operator= ( const captured_exception& src ) {
00205 if ( this != &src ) {
00206 clear();
00207 set(src.my_exception_name, src.my_exception_info);
00208 }
00209 return *this;
00210 }
00211
00212
00213 captured_exception* __TBB_EXPORTED_METHOD move () throw();
00214
00215
00216 void __TBB_EXPORTED_METHOD destroy () throw();
00217
00218
00219 void throw_self () { __TBB_THROW(*this); }
00220
00221
00222 const char* __TBB_EXPORTED_METHOD name() const throw();
00223
00224
00225 const char* __TBB_EXPORTED_METHOD what() const throw();
00226
00227 void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00228 void __TBB_EXPORTED_METHOD clear () throw();
00229
00230 private:
00232 captured_exception() {}
00233
00235 static captured_exception* allocate ( const char* name, const char* info );
00236
00237 bool my_dynamic;
00238 const char* my_exception_name;
00239 const char* my_exception_info;
00240 };
00241
00243
00247 template<typename ExceptionData>
00248 class movable_exception : public tbb_exception
00249 {
00250 typedef movable_exception<ExceptionData> self_type;
00251
00252 public:
00253 movable_exception ( const ExceptionData& data_ )
00254 : my_exception_data(data_)
00255 , my_dynamic(false)
00256 , my_exception_name(
00257 #if TBB_USE_EXCEPTIONS
00258 typeid(self_type).name()
00259 #else
00260 "movable_exception"
00261 #endif
00262 )
00263 {}
00264
00265 movable_exception ( const movable_exception& src ) throw ()
00266 : tbb_exception(src)
00267 , my_exception_data(src.my_exception_data)
00268 , my_dynamic(false)
00269 , my_exception_name(src.my_exception_name)
00270 {}
00271
00272 ~movable_exception () throw() {}
00273
00274 const movable_exception& operator= ( const movable_exception& src ) {
00275 if ( this != &src ) {
00276 my_exception_data = src.my_exception_data;
00277 my_exception_name = src.my_exception_name;
00278 }
00279 return *this;
00280 }
00281
00282 ExceptionData& data () throw() { return my_exception_data; }
00283
00284 const ExceptionData& data () const throw() { return my_exception_data; }
00285
00286 const char* name () const throw() { return my_exception_name; }
00287
00288 const char* what () const throw() { return "tbb::movable_exception"; }
00289
00290
00291 movable_exception* move () throw() {
00292 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00293 if ( e ) {
00294 ::new (e) movable_exception(*this);
00295 ((movable_exception*)e)->my_dynamic = true;
00296 }
00297 return (movable_exception*)e;
00298 }
00299
00300 void destroy () throw() {
00301 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00302 if ( my_dynamic ) {
00303 this->~movable_exception();
00304 internal::deallocate_via_handler_v3(this);
00305 }
00306 }
00307
00308 void throw_self () { __TBB_THROW( *this ); }
00309
00310 protected:
00312 ExceptionData my_exception_data;
00313
00314 private:
00316 bool my_dynamic;
00317
00319
00320 const char* my_exception_name;
00321 };
00322
00323 #if !TBB_USE_CAPTURED_EXCEPTION
00324 namespace internal {
00325
00327
00329 class tbb_exception_ptr {
00330 std::exception_ptr my_ptr;
00331
00332 public:
00333 static tbb_exception_ptr* allocate ();
00334 static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00336 static tbb_exception_ptr* allocate ( captured_exception& src );
00337
00339
00340 void destroy () throw();
00341
00343 void throw_self () { std::rethrow_exception(my_ptr); }
00344
00345 private:
00346 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00347 tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
00348 };
00349
00350 }
00351 #endif
00352
00353 }
00354
00355 #endif
00356
00357 #endif