tbb_exception.h

00001 /*
00002     Copyright 2005-2010 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 
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> // required to construct std exception classes
00033 #endif
00034 
00035 namespace tbb {
00036 
00038 class bad_last_alloc : public std::bad_alloc {
00039 public:
00040     /*override*/ const char* what() const throw();
00043     /*override*/ ~bad_last_alloc() throw() {}
00044 };
00045 
00047 class improper_lock : public std::exception {
00048 public:
00049     /*override*/ const char* what() const throw();
00050 };
00051 
00053 class missing_wait : public std::exception {
00054 public:
00055     /*override*/ const char* what() const throw();
00056 };
00057 
00059 class invalid_multiple_scheduling : public std::exception {
00060 public:
00061     /*override*/ 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 } // namespace internal
00092 
00093 } // namespace tbb
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     /*override*/ 
00198     captured_exception* __TBB_EXPORTED_METHOD move () throw();
00199 
00200     /*override*/ 
00201     void __TBB_EXPORTED_METHOD destroy () throw();
00202 
00203     /*override*/ 
00204     void throw_self () { throw *this; }
00205 
00206     /*override*/ 
00207     const char* __TBB_EXPORTED_METHOD name() const throw();
00208 
00209     /*override*/ 
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     /*override*/ const char* name () const throw() { return my_exception_name; }
00266 
00267     /*override*/ const char* what () const throw() { return "tbb::movable_exception"; }
00268 
00269     /*override*/ 
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     /*override*/ 
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     /*override*/ 
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 }; // class tbb::internal::tbb_exception_ptr
00330 
00331 } // namespace internal
00332 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
00333 
00334 } // namespace tbb
00335 
00336 #endif /* __TBB_EXCEPTIONS */
00337 
00338 #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.