Boost Exception supports transporting of exception objects between threads through cloning. This system is similar to N2179, but because Boost Exception can not rely on language support, the use of enable_current_exception() at the time of the throw is required in order to use cloning.
All exceptions emitted by the familiar function boost::throw_exception() are guaranteed to derive from boost::exception and to support cloning.
Here is how cloning can be enabled in a throw-expression (15.1):
#include <boost/exception/enable_current_exception.hpp> #include <boost/exception/info.hpp> #include <stdio.h> #include <errno.h> typedef boost::error_info<struct tag_errno,int> errno_info; class file_read_error: public boost::exception { }; void file_read( FILE * f, void * buffer, size_t size ) { if( size!=fread(buffer,1,size,f) ) throw boost::enable_current_exception(file_read_error()) << errno_info(errno); }
When you catch a boost::exception, you can call current_exception() to get an exception_ptr object:
#include <boost/exception_ptr.hpp> #include <boost/thread.hpp> #include <boost/bind.hpp> void do_work(); //throws cloning-enabled boost::exceptions void worker_thread( boost::exception_ptr & error ) { try { do_work(); error = boost::exception_ptr(); } catch( ... ) { error = boost::current_exception(); } }
In the above example, note that current_exception() captures the original type of the exception object. The exception can be thrown again using the rethrow_exception() function:
// ...continued void work() { boost::exception_ptr error; boost::thread t( boost::bind(worker_thread,boost::ref(error)) ); t.join(); if( error ) boost::rethrow_exception(error); }
current_exception() could fail to copy the original exception object in the following cases:
Regardless, the use of current_exception() and rethrow_exception() in the above examples is well-formed.