Shadowrun: Awakened 29 September 2011 - Build 871
tbb_exception.h
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2010 Intel Corporation.  All Rights Reserved.
00003 
00004     This file is part of Threading Building Blocks.
00005 
00006     Threading Building Blocks is free software; you can redistribute it
00007     and/or modify it under the terms of the GNU General Public License
00008     version 2 as published by the Free Software Foundation.
00009 
00010     Threading Building Blocks is distributed in the hope that it will be
00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Threading Building Blocks; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019     As a special exception, you may use this file as part of a free software
00020     library without restriction.  Specifically, if other files instantiate
00021     templates or use macros or inline functions from this file, or you compile
00022     this file and link it with other files to produce an executable, this
00023     file does not by itself cause the resulting executable to be covered by
00024     the GNU General Public License.  This exception does not however
00025     invalidate any other reasons why the executable file might be covered by
00026     the GNU General Public License.
00027 */
00028 
00029 #ifndef __TBB_exception_H
00030 #define __TBB_exception_H
00031 
00032 #include "tbb_stddef.h"
00033 
00034 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00035     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
00036     #pragma warning (push)
00037     #pragma warning (disable: 4530)
00038 #endif
00039 
00040 #include <stdexcept>
00041 
00042 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00043     #pragma warning (pop)
00044 #endif
00045 
00046 #if __SUNPRO_CC
00047 #include <string> // required to construct std exception classes
00048 #endif
00049 
00050 namespace tbb {
00051 
00053 class bad_last_alloc : public std::bad_alloc {
00054 public:
00055     /*override*/ const char* what() const throw();
00056 #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN
00057     /*override*/ ~bad_last_alloc() throw() {}
00058 #endif
00059 };
00060 
00062 class improper_lock : public std::exception {
00063 public:
00064     /*override*/ const char* what() const throw();
00065 };
00066 
00068 class missing_wait : public std::exception {
00069 public:
00070     /*override*/ const char* what() const throw();
00071 };
00072 
00074 class invalid_multiple_scheduling : public std::exception {
00075 public:
00076     /*override*/ const char* what() const throw();
00077 };
00078 
00079 namespace internal {
00081 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();
00082 
00083 enum exception_id {
00084     eid_bad_alloc = 1,
00085     eid_bad_last_alloc,
00086     eid_nonpositive_step,
00087     eid_out_of_range,
00088     eid_segment_range_error,
00089     eid_index_range_error,
00090     eid_missing_wait,
00091     eid_invalid_multiple_scheduling,
00092     eid_improper_lock,
00093     eid_possible_deadlock,
00094     eid_operation_not_permitted,
00095     eid_condvar_wait_failed,
00096     eid_invalid_load_factor,
00097     eid_invalid_buckets_number,
00098     eid_invalid_swap,
00099     eid_reservation_length_error,
00100     eid_invalid_key,
00102 
00104     eid_max
00105 };
00106 
00108 
00110 void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );
00111 
00113 inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
00114 
00115 } // namespace internal
00116 } // namespace tbb
00117 
00118 #if __TBB_TASK_GROUP_CONTEXT
00119 #include "tbb_allocator.h"
00120 #include <exception>
00121 #include <typeinfo>
00122 #include <new>
00123 
00124 namespace tbb {
00125 
00127 
00147 class tbb_exception : public std::exception
00148 {
00152     void* operator new ( size_t );
00153 
00154 public:
00156 
00157     virtual tbb_exception* move () throw() = 0;
00158     
00160 
00162     virtual void destroy () throw() = 0;
00163 
00165 
00169     virtual void throw_self () = 0;
00170 
00172     virtual const char* name() const throw() = 0;
00173 
00175     virtual const char* what() const throw() = 0;
00176 
00183     void operator delete ( void* p ) {
00184         internal::deallocate_via_handler_v3(p);
00185     }
00186 };
00187 
00189 
00193 class captured_exception : public tbb_exception
00194 {
00195 public:
00196     captured_exception ( const captured_exception& src )
00197         : tbb_exception(src), my_dynamic(false)
00198     {
00199         set(src.my_exception_name, src.my_exception_info);
00200     }
00201 
00202     captured_exception ( const char* name_, const char* info )
00203         : my_dynamic(false)
00204     {
00205         set(name_, info);
00206     }
00207 
00208     __TBB_EXPORTED_METHOD ~captured_exception () throw() {
00209         clear();
00210     }
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 ) : my_ptr(std::copy_exception(src)) {}
00356 }; // class tbb::internal::tbb_exception_ptr
00357 
00358 } // namespace internal
00359 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
00360 
00361 } // namespace tbb
00362 
00363 #endif /* __TBB_TASK_GROUP_CONTEXT */
00364 
00365 #endif /* __TBB_exception_H */

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net