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_EXCEPTIONS && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) && !defined(__SUNPRO_CC)
00027 #error The current compilation environment does not support exception handling. Please set __TBB_EXCEPTIONS to 0 in tbb_config.h
00028 #endif
00029
00030 #include <stdexcept>
00031 #if __SUNPRO_CC
00032 #include <string>
00033 #endif
00034
00035 namespace tbb {
00036
00038 class bad_last_alloc : public std::bad_alloc {
00039 public:
00040 const char* what() const throw();
00043 ~bad_last_alloc() throw() {}
00044 };
00045
00047 class improper_lock : public std::exception {
00048 public:
00049 const char* what() const throw();
00050 };
00051
00053 class missing_wait : public std::exception {
00054 public:
00055 const char* what() const throw();
00056 };
00057
00059 class invalid_multiple_scheduling : public std::exception {
00060 public:
00061 const char* what() const throw();
00062 };
00063
00064 namespace internal {
00066 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();
00067
00068 enum exception_id {
00069 eid_bad_alloc = 1,
00070 eid_bad_last_alloc,
00071 eid_nonpositive_step,
00072 eid_out_of_range,
00073 eid_segment_range_error,
00074 eid_index_range_error,
00075 eid_missing_wait,
00076 eid_invalid_multiple_scheduling,
00077 eid_improper_lock,
00079
00081 eid_max
00082 };
00083
00085
00087 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
00088
00090 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
00091 }
00092
00093 }
00094
00095 #if __TBB_EXCEPTIONS
00096 #include "tbb_allocator.h"
00097 #include <exception>
00098 #include <typeinfo>
00099 #include <new>
00100
00101 namespace tbb {
00102
00104
00124 class tbb_exception : public std::exception
00125 {
00129 void* operator new ( size_t );
00130
00131 public:
00133
00134 virtual tbb_exception* move () throw() = 0;
00135
00137
00139 virtual void destroy () throw() = 0;
00140
00142
00146 virtual void throw_self () = 0;
00147
00149 virtual const char* name() const throw() = 0;
00150
00152 virtual const char* what() const throw() = 0;
00153
00160 void operator delete ( void* p ) {
00161 internal::deallocate_via_handler_v3(p);
00162 }
00163 };
00164
00166
00170 class captured_exception : public tbb_exception
00171 {
00172 public:
00173 captured_exception ( const captured_exception& src )
00174 : tbb_exception(src), my_dynamic(false)
00175 {
00176 set(src.my_exception_name, src.my_exception_info);
00177 }
00178
00179 captured_exception ( const char* name, const char* info )
00180 : my_dynamic(false)
00181 {
00182 set(name, info);
00183 }
00184
00185 __TBB_EXPORTED_METHOD ~captured_exception () throw() {
00186 clear();
00187 }
00188
00189 captured_exception& operator= ( const captured_exception& src ) {
00190 if ( this != &src ) {
00191 clear();
00192 set(src.my_exception_name, src.my_exception_info);
00193 }
00194 return *this;
00195 }
00196
00197
00198 captured_exception* __TBB_EXPORTED_METHOD move () throw();
00199
00200
00201 void __TBB_EXPORTED_METHOD destroy () throw();
00202
00203
00204 void throw_self () { throw *this; }
00205
00206
00207 const char* __TBB_EXPORTED_METHOD name() const throw();
00208
00209
00210 const char* __TBB_EXPORTED_METHOD what() const throw();
00211
00212 void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00213 void __TBB_EXPORTED_METHOD clear () throw();
00214
00215 private:
00217 captured_exception() {}
00218
00220 static captured_exception* allocate ( const char* name, const char* info );
00221
00222 bool my_dynamic;
00223 const char* my_exception_name;
00224 const char* my_exception_info;
00225 };
00226
00228
00232 template<typename ExceptionData>
00233 class movable_exception : public tbb_exception
00234 {
00235 typedef movable_exception<ExceptionData> self_type;
00236
00237 public:
00238 movable_exception ( const ExceptionData& data )
00239 : my_exception_data(data)
00240 , my_dynamic(false)
00241 , my_exception_name(typeid(self_type).name())
00242 {}
00243
00244 movable_exception ( const movable_exception& src ) throw ()
00245 : tbb_exception(src)
00246 , my_exception_data(src.my_exception_data)
00247 , my_dynamic(false)
00248 , my_exception_name(src.my_exception_name)
00249 {}
00250
00251 ~movable_exception () throw() {}
00252
00253 const movable_exception& operator= ( const movable_exception& src ) {
00254 if ( this != &src ) {
00255 my_exception_data = src.my_exception_data;
00256 my_exception_name = src.my_exception_name;
00257 }
00258 return *this;
00259 }
00260
00261 ExceptionData& data () throw() { return my_exception_data; }
00262
00263 const ExceptionData& data () const throw() { return my_exception_data; }
00264
00265 const char* name () const throw() { return my_exception_name; }
00266
00267 const char* what () const throw() { return "tbb::movable_exception"; }
00268
00269
00270 movable_exception* move () throw() {
00271 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00272 if ( e ) {
00273 ::new (e) movable_exception(*this);
00274 ((movable_exception*)e)->my_dynamic = true;
00275 }
00276 return (movable_exception*)e;
00277 }
00278
00279 void destroy () throw() {
00280 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00281 if ( my_dynamic ) {
00282 this->~movable_exception();
00283 internal::deallocate_via_handler_v3(this);
00284 }
00285 }
00286
00287 void throw_self () {
00288 throw *this;
00289 }
00290
00291 protected:
00293 ExceptionData my_exception_data;
00294
00295 private:
00297 bool my_dynamic;
00298
00300
00301 const char* my_exception_name;
00302 };
00303
00304 #if !TBB_USE_CAPTURED_EXCEPTION
00305 namespace internal {
00306
00308
00310 class tbb_exception_ptr {
00311 std::exception_ptr my_ptr;
00312
00313 public:
00314 static tbb_exception_ptr* allocate ();
00315 static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00317 static tbb_exception_ptr* allocate ( captured_exception& src );
00318
00320
00321 void destroy () throw();
00322
00324 void throw_self () { std::rethrow_exception(my_ptr); }
00325
00326 private:
00327 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00328 tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
00329 };
00330
00331 }
00332 #endif
00333
00334 }
00335
00336 #endif
00337
00338 #endif