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_USE_EXCEPTIONS && _MSC_VER
00027     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
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> // required to construct std exception classes
00040 #endif
00041 
00042 namespace tbb {
00043 
00045 class bad_last_alloc : public std::bad_alloc {
00046 public:
00047     /*override*/ const char* what() const throw();
00048 #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN
00049     /*override*/ ~bad_last_alloc() throw() {}
00050 #endif
00051 };
00052 
00054 class improper_lock : public std::exception {
00055 public:
00056     /*override*/ const char* what() const throw();
00057 };
00058 
00060 class missing_wait : public std::exception {
00061 public:
00062     /*override*/ const char* what() const throw();
00063 };
00064 
00066 class invalid_multiple_scheduling : public std::exception {
00067 public:
00068     /*override*/ 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_reserved, // free slot for backward compatibility, can be reused.
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 } // namespace internal
00108 } // namespace tbb
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     /*override*/ 
00213     captured_exception* __TBB_EXPORTED_METHOD move () throw();
00214 
00215     /*override*/ 
00216     void __TBB_EXPORTED_METHOD destroy () throw();
00217 
00218     /*override*/ 
00219     void throw_self () { __TBB_THROW(*this); }
00220 
00221     /*override*/ 
00222     const char* __TBB_EXPORTED_METHOD name() const throw();
00223 
00224     /*override*/ 
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 /* !TBB_USE_EXCEPTIONS */
00260         "movable_exception"
00261 #endif /* !TBB_USE_EXCEPTIONS */
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     /*override*/ const char* name () const throw() { return my_exception_name; }
00287 
00288     /*override*/ const char* what () const throw() { return "tbb::movable_exception"; }
00289 
00290     /*override*/ 
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     /*override*/ 
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     /*override*/ 
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 }; // class tbb::internal::tbb_exception_ptr
00349 
00350 } // namespace internal
00351 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
00352 
00353 } // namespace tbb
00354 
00355 #endif /* __TBB_TASK_GROUP_CONTEXT */
00356 
00357 #endif /* __TBB_exception_H */

Copyright © 2005-2010 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.