- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# tbb_exception.h

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

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