tbb_exception.h

00001 /*
00002     Copyright 2005-2009 Intel Corporation.  All Rights Reserved.
00003 
00004     The source code contained or described herein and all documents related
00005     to the source code ("Material") are owned by Intel Corporation or its
00006     suppliers or licensors.  Title to the Material remains with Intel
00007     Corporation or its suppliers and licensors.  The Material is protected
00008     by worldwide copyright laws and treaty provisions.  No part of the
00009     Material may be used, copied, reproduced, modified, published, uploaded,
00010     posted, transmitted, distributed, or disclosed in any way without
00011     Intel's prior express written permission.
00012 
00013     No license under any patent, copyright, trade secret or other
00014     intellectual property right is granted to or conferred upon you by
00015     disclosure or delivery of the Materials, either expressly, by
00016     implication, inducement, estoppel or otherwise.  Any license under such
00017     intellectual property rights must be express and approved by Intel in
00018     writing.
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 } // namespace internal
00043 
00044 } // namespace tbb
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 {
00080     void* operator new ( size_t );
00081 
00082 public:
00084 
00085     virtual tbb_exception* move () throw() = 0;
00086     
00088 
00090     virtual void destroy () throw() = 0;
00091 
00093 
00097     virtual void throw_self () = 0;
00098 
00100     virtual const char* name() const throw() = 0;
00101 
00103     virtual const char* what() const throw() = 0;
00104 
00111     void operator delete ( void* p ) {
00112         internal::deallocate_via_handler_v3(p);
00113     }
00114 };
00115 
00117 
00121 class captured_exception : public tbb_exception
00122 {
00123 public:
00124     captured_exception ( const captured_exception& src )
00125         : tbb_exception(src), my_dynamic(false)
00126     {
00127         set(src.my_exception_name, src.my_exception_info);
00128     }
00129 
00130     captured_exception ( const char* name, const char* info )
00131         : my_dynamic(false)
00132     {
00133         set(name, info);
00134     }
00135 
00136     __TBB_EXPORTED_METHOD ~captured_exception () throw() {
00137         clear();
00138     }
00139 
00140     captured_exception& operator= ( const captured_exception& src ) {
00141         if ( this != &src ) {
00142             clear();
00143             set(src.my_exception_name, src.my_exception_info);
00144         }
00145         return *this;
00146     }
00147 
00148     /*override*/ 
00149     captured_exception* __TBB_EXPORTED_METHOD move () throw();
00150 
00151     /*override*/ 
00152     void __TBB_EXPORTED_METHOD destroy () throw();
00153 
00154     /*override*/ 
00155     void throw_self () { throw *this; }
00156 
00157     /*override*/ 
00158     const char* __TBB_EXPORTED_METHOD name() const throw();
00159 
00160     /*override*/ 
00161     const char* __TBB_EXPORTED_METHOD what() const throw();
00162 
00163     void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00164     void __TBB_EXPORTED_METHOD clear () throw();
00165 
00166 private:
00168     captured_exception() {}
00169 
00171     static captured_exception* allocate ( const char* name, const char* info );
00172 
00173     bool my_dynamic;
00174     const char* my_exception_name;
00175     const char* my_exception_info;
00176 };
00177 
00179 
00183 template<typename ExceptionData>
00184 class movable_exception : public tbb_exception
00185 {
00186     typedef movable_exception<ExceptionData> self_type;
00187 
00188 public:
00189     movable_exception ( const ExceptionData& data ) 
00190         : my_exception_data(data)
00191         , my_dynamic(false)
00192         , my_exception_name(typeid(self_type).name())
00193     {}
00194 
00195     movable_exception ( const movable_exception& src ) throw () 
00196         : tbb_exception(src)
00197         , my_exception_data(src.my_exception_data)
00198         , my_dynamic(false)
00199         , my_exception_name(src.my_exception_name)
00200     {}
00201 
00202     ~movable_exception () throw() {}
00203 
00204     const movable_exception& operator= ( const movable_exception& src ) {
00205         if ( this != &src ) {
00206             my_exception_data = src.my_exception_data;
00207             my_exception_name = src.my_exception_name;
00208         }
00209         return *this;
00210     }
00211 
00212     ExceptionData& data () throw() { return my_exception_data; }
00213 
00214     const ExceptionData& data () const throw() { return my_exception_data; }
00215 
00216     /*override*/ const char* name () const throw() { return my_exception_name; }
00217 
00218     /*override*/ const char* what () const throw() { return "tbb::movable_exception"; }
00219 
00220     /*override*/ 
00221     movable_exception* move () throw() {
00222         void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00223         if ( e ) {
00224             ::new (e) movable_exception(*this);
00225             ((movable_exception*)e)->my_dynamic = true;
00226         }
00227         return (movable_exception*)e;
00228     }
00229     /*override*/ 
00230     void destroy () throw() {
00231         __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00232         if ( my_dynamic ) {
00233             this->~movable_exception();
00234             internal::deallocate_via_handler_v3(this);
00235         }
00236     }
00237     /*override*/ 
00238     void throw_self () {
00239         throw *this;
00240     }
00241 
00242 protected:
00244     ExceptionData  my_exception_data;
00245 
00246 private:
00248     bool my_dynamic;
00249 
00251 
00252     const char* my_exception_name;
00253 };
00254 
00255 #if !TBB_USE_CAPTURED_EXCEPTION
00256 namespace internal {
00257 
00259 
00261 class tbb_exception_ptr {
00262     std::exception_ptr  my_ptr;
00263 
00264 public:
00265     static tbb_exception_ptr* allocate ();
00266     static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00268     static tbb_exception_ptr* allocate ( captured_exception& src );
00269     
00271 
00272     void destroy () throw();
00273 
00275     void throw_self () { std::rethrow_exception(my_ptr); }
00276 
00277 private:
00278     tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00279     tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
00280 }; // class tbb::internal::tbb_exception_ptr
00281 
00282 } // namespace internal
00283 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
00284 
00285 } // namespace tbb
00286 
00287 #endif /* __TBB_EXCEPTIONS */
00288 
00289 #endif /* __TBB_exception_H */

Copyright © 2005-2009 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.