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 #include <stdexcept>
00026
00027 #if __TBB_EXCEPTIONS && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) && !defined(__SUNPRO_CC)
00028 #error The current compilation environment does not support exception handling. Please set __TBB_EXCEPTIONS to 0 in tbb_config.h
00029 #endif
00030
00031 namespace tbb {
00032
00034 class bad_last_alloc : public std::bad_alloc {
00035 public:
00036 virtual const char* what() const throw() { return "bad allocation in previous or concurrent attempt"; }
00037 virtual ~bad_last_alloc() throw() {}
00038 };
00039
00040 namespace internal {
00041 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4() ;
00042 }
00043
00044 }
00045
00046 #if __TBB_EXCEPTIONS
00047 #include "tbb_allocator.h"
00048 #include <exception>
00049 #include <typeinfo>
00050 #include <new>
00051
00052 namespace tbb {
00053
00055
00075 class tbb_exception : public std::exception {
00076 public:
00078
00079 virtual tbb_exception* move () throw() = 0;
00080
00082
00084 virtual void destroy () throw() = 0;
00085
00087
00091 virtual void throw_self () = 0;
00092
00094 virtual const char* name() const throw() = 0;
00095
00097 virtual const char* what() const throw() = 0;
00098 };
00099
00101
00105 class captured_exception : public tbb_exception
00106 {
00107 public:
00108 captured_exception ( const captured_exception& src )
00109 : tbb_exception(src), my_dynamic(false)
00110 {
00111 set(src.my_exception_name, src.my_exception_info);
00112 }
00113
00114 captured_exception ( const char* name, const char* info )
00115 : my_dynamic(false)
00116 {
00117 set(name, info);
00118 }
00119
00120 __TBB_EXPORTED_METHOD ~captured_exception () throw() {
00121 clear();
00122 }
00123
00124 captured_exception& operator= ( const captured_exception& src ) {
00125 if ( this != &src ) {
00126 clear();
00127 set(src.my_exception_name, src.my_exception_info);
00128 }
00129 return *this;
00130 }
00131
00132
00133 captured_exception* move () throw();
00134
00135
00136 void destroy () throw();
00137
00138
00139 void throw_self () { throw *this; }
00140
00141
00142 const char* __TBB_EXPORTED_METHOD name() const throw();
00143
00144
00145 const char* __TBB_EXPORTED_METHOD what() const throw();
00146
00147 private:
00149 captured_exception() {}
00150
00152 static captured_exception* allocate ( const char* name, const char* info );
00153
00154 void set ( const char* name, const char* info ) throw();
00155 void clear () throw();
00156
00157 bool my_dynamic;
00158 const char* my_exception_name;
00159 const char* my_exception_info;
00160 };
00161
00163
00167 template<typename ExceptionData>
00168 class movable_exception : public tbb_exception
00169 {
00170 typedef movable_exception<ExceptionData> self_type;
00171
00172 public:
00173 movable_exception ( const ExceptionData& data )
00174 : my_exception_data(data)
00175 , my_dynamic(false)
00176 , my_exception_name(typeid(self_type).name())
00177 {}
00178
00179 movable_exception ( const movable_exception& src ) throw ()
00180 : tbb_exception(src)
00181 , my_exception_data(src.my_exception_data)
00182 , my_dynamic(false)
00183 , my_exception_name(src.my_exception_name)
00184 {}
00185
00186 ~movable_exception () throw() {}
00187
00188 const movable_exception& operator= ( const movable_exception& src ) {
00189 if ( this != &src ) {
00190 my_exception_data = src.my_exception_data;
00191 my_exception_name = src.my_exception_name;
00192 }
00193 return *this;
00194 }
00195
00196 ExceptionData& data () throw() { return my_exception_data; }
00197
00198 const ExceptionData& data () const throw() { return my_exception_data; }
00199
00200 const char* name () const throw() { return my_exception_name; }
00201
00202 const char* what () const throw() { return "tbb::movable_exception"; }
00203
00204
00205 movable_exception* move () throw() {
00206 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00207 if ( e ) {
00208 new (e) movable_exception(*this);
00209 ((movable_exception*)e)->my_dynamic = true;
00210 }
00211 return (movable_exception*)e;
00212 }
00213
00214 void destroy () throw() {
00215 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00216 if ( my_dynamic ) {
00217 this->~movable_exception();
00218 internal::deallocate_via_handler_v3(this);
00219 }
00220 }
00221
00222 void throw_self () {
00223 throw *this;
00224 }
00225
00226 protected:
00228 ExceptionData my_exception_data;
00229
00230 private:
00232 bool my_dynamic;
00233
00235
00236 const char* my_exception_name;
00237 };
00238
00239 #if !TBB_USE_CAPTURED_EXCEPTION
00240 namespace internal {
00241
00243
00245 class tbb_exception_ptr {
00246 std::exception_ptr my_ptr;
00247
00248 public:
00249 static tbb_exception_ptr* allocate ();
00250 static tbb_exception_ptr* allocate ( const tbb_exception& );
00251 static tbb_exception_ptr* allocate ( const captured_exception& );
00252
00254
00255 void destroy () throw();
00256
00258 void throw_self () { std::rethrow_exception(my_ptr); }
00259
00260 private:
00261 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00262 tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
00263 };
00264
00265 }
00266 #endif
00267
00268 }
00269
00270 #endif
00271
00272 #endif