tbb_exception.h

00001 /*
00002     Copyright 2005-2013 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 #include <string> // required to construct std exception classes
00034 
00035 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00036     #pragma warning (pop)
00037 #endif
00038 
00039 namespace tbb {
00040 
00042 class bad_last_alloc : public std::bad_alloc {
00043 public:
00044     /*override*/ const char* what() const throw();
00045 #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN
00046     /*override*/ ~bad_last_alloc() throw() {}
00047 #endif
00048 };
00049 
00051 class improper_lock : public std::exception {
00052 public:
00053     /*override*/ const char* what() const throw();
00054 };
00055 
00057 class user_abort : public std::exception {
00058 public:
00059     /*override*/ const char* what() const throw();
00060 };
00061 
00063 class missing_wait : public std::exception {
00064 public:
00065     /*override*/ const char* what() const throw();
00066 };
00067 
00069 class invalid_multiple_scheduling : public std::exception {
00070 public:
00071     /*override*/ const char* what() const throw();
00072 };
00073 
00074 namespace internal {
00076 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();
00077 
00078 enum exception_id {
00079     eid_bad_alloc = 1,
00080     eid_bad_last_alloc,
00081     eid_nonpositive_step,
00082     eid_out_of_range,
00083     eid_segment_range_error,
00084     eid_index_range_error,
00085     eid_missing_wait,
00086     eid_invalid_multiple_scheduling,
00087     eid_improper_lock,
00088     eid_possible_deadlock,
00089     eid_operation_not_permitted,
00090     eid_condvar_wait_failed,
00091     eid_invalid_load_factor,
00092     eid_reserved, // free slot for backward compatibility, can be reused.
00093     eid_invalid_swap,
00094     eid_reservation_length_error,
00095     eid_invalid_key,
00096     eid_user_abort,
00097     eid_reserved1,
00098 #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
00099     // This id is used only inside library and only for support of CPF functionality.
00100     // So, if we drop the functionality, eid_reserved1 can be safely renamed and reused.
00101     eid_blocking_sch_init = eid_reserved1,
00102 #endif
00104 
00106     eid_max
00107 };
00108 
00110 
00112 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
00113 
00115 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
00116 
00117 } // namespace internal
00118 } // namespace tbb
00119 
00120 #if __TBB_TASK_GROUP_CONTEXT
00121 #include "tbb_allocator.h"
00122 #include <exception>
00123 #include <typeinfo>
00124 #include <new>
00125 
00126 namespace tbb {
00127 
00129 
00149 class tbb_exception : public std::exception
00150 {
00154     void* operator new ( size_t );
00155 
00156 public:
00158 
00159     virtual tbb_exception* move () throw() = 0;
00160 
00162 
00164     virtual void destroy () throw() = 0;
00165 
00167 
00171     virtual void throw_self () = 0;
00172 
00174     virtual const char* name() const throw() = 0;
00175 
00177     virtual const char* what() const throw() = 0;
00178 
00185     void operator delete ( void* p ) {
00186         internal::deallocate_via_handler_v3(p);
00187     }
00188 };
00189 
00191 
00195 class captured_exception : public tbb_exception
00196 {
00197 public:
00198     captured_exception ( const captured_exception& src )
00199         : tbb_exception(src), my_dynamic(false)
00200     {
00201         set(src.my_exception_name, src.my_exception_info);
00202     }
00203 
00204     captured_exception ( const char* name_, const char* info )
00205         : my_dynamic(false)
00206     {
00207         set(name_, info);
00208     }
00209 
00210     __TBB_EXPORTED_METHOD ~captured_exception () throw();
00211 
00212     captured_exception& operator= ( const captured_exception& src ) {
00213         if ( this != &src ) {
00214             clear();
00215             set(src.my_exception_name, src.my_exception_info);
00216         }
00217         return *this;
00218     }
00219 
00220     /*override*/
00221     captured_exception* __TBB_EXPORTED_METHOD move () throw();
00222 
00223     /*override*/
00224     void __TBB_EXPORTED_METHOD destroy () throw();
00225 
00226     /*override*/
00227     void throw_self () { __TBB_THROW(*this); }
00228 
00229     /*override*/
00230     const char* __TBB_EXPORTED_METHOD name() const throw();
00231 
00232     /*override*/
00233     const char* __TBB_EXPORTED_METHOD what() const throw();
00234 
00235     void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00236     void __TBB_EXPORTED_METHOD clear () throw();
00237 
00238 private:
00240     captured_exception() {}
00241 
00243     static captured_exception* allocate ( const char* name, const char* info );
00244 
00245     bool my_dynamic;
00246     const char* my_exception_name;
00247     const char* my_exception_info;
00248 };
00249 
00251 
00255 template<typename ExceptionData>
00256 class movable_exception : public tbb_exception
00257 {
00258     typedef movable_exception<ExceptionData> self_type;
00259 
00260 public:
00261     movable_exception ( const ExceptionData& data_ )
00262         : my_exception_data(data_)
00263         , my_dynamic(false)
00264         , my_exception_name(
00265 #if TBB_USE_EXCEPTIONS
00266         typeid(self_type).name()
00267 #else /* !TBB_USE_EXCEPTIONS */
00268         "movable_exception"
00269 #endif /* !TBB_USE_EXCEPTIONS */
00270         )
00271     {}
00272 
00273     movable_exception ( const movable_exception& src ) throw ()
00274         : tbb_exception(src)
00275         , my_exception_data(src.my_exception_data)
00276         , my_dynamic(false)
00277         , my_exception_name(src.my_exception_name)
00278     {}
00279 
00280     ~movable_exception () throw() {}
00281 
00282     const movable_exception& operator= ( const movable_exception& src ) {
00283         if ( this != &src ) {
00284             my_exception_data = src.my_exception_data;
00285             my_exception_name = src.my_exception_name;
00286         }
00287         return *this;
00288     }
00289 
00290     ExceptionData& data () throw() { return my_exception_data; }
00291 
00292     const ExceptionData& data () const throw() { return my_exception_data; }
00293 
00294     /*override*/ const char* name () const throw() { return my_exception_name; }
00295 
00296     /*override*/ const char* what () const throw() { return "tbb::movable_exception"; }
00297 
00298     /*override*/
00299     movable_exception* move () throw() {
00300         void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00301         if ( e ) {
00302             ::new (e) movable_exception(*this);
00303             ((movable_exception*)e)->my_dynamic = true;
00304         }
00305         return (movable_exception*)e;
00306     }
00307     /*override*/
00308     void destroy () throw() {
00309         __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00310         if ( my_dynamic ) {
00311             this->~movable_exception();
00312             internal::deallocate_via_handler_v3(this);
00313         }
00314     }
00315     /*override*/
00316     void throw_self () { __TBB_THROW( *this ); }
00317 
00318 protected:
00320     ExceptionData  my_exception_data;
00321 
00322 private:
00324     bool my_dynamic;
00325 
00327 
00328     const char* my_exception_name;
00329 };
00330 
00331 #if !TBB_USE_CAPTURED_EXCEPTION
00332 namespace internal {
00333 
00335 
00337 class tbb_exception_ptr {
00338     std::exception_ptr  my_ptr;
00339 
00340 public:
00341     static tbb_exception_ptr* allocate ();
00342     static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00344     static tbb_exception_ptr* allocate ( captured_exception& src );
00345 
00347 
00348     void destroy () throw();
00349 
00351     void throw_self () { std::rethrow_exception(my_ptr); }
00352 
00353 private:
00354     tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00355     tbb_exception_ptr ( const captured_exception& src ) :
00356         #if __TBB_MAKE_EXCEPTION_PTR_PRESENT
00357             my_ptr(std::make_exception_ptr(src))  // the final function name in C++11
00358         #else
00359             my_ptr(std::copy_exception(src))      // early C++0x drafts name
00360         #endif
00361     {}
00362 }; // class tbb::internal::tbb_exception_ptr
00363 
00364 } // namespace internal
00365 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
00366 
00367 } // namespace tbb
00368 
00369 #endif /* __TBB_TASK_GROUP_CONTEXT */
00370 
00371 #endif /* __TBB_exception_H */

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