Opened 12 years ago
Closed 10 years ago
#5351 closed Patches (fixed)
interrupt a future get boost::unknown_exception
Reported by: | Owned by: | viboes | |
---|---|---|---|
Milestone: | Boost 1.50.0 | Component: | thread |
Version: | Boost 1.46.0 | Severity: | Problem |
Keywords: | thread interrupt future unknown_exception | Cc: | viboes |
Description
It may be a bug of the thread or future. in boost_1_46_0/doc/html/thread/synchronization.html it says: these Member functions: shared_future class template: Member function get() Member function wait() Member function timed_wait() and unique_future class template: Member function get() Member function wait() Member function timed_wait() Throws: ........ boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the [current] thread is interrupted. ............ but it throws boost::unknown_exception. and the [current] thread is interrupted. Should be the [working] thread is interrupted ? > > [Windows XP, VC++ 10, boost 1.46] > > When interrupt a future, the future.get() throw boost::unknown_exception, > > Not boost::thread_interrupted. > > > > Class boost::thread_interrupted should have a base class for > > current_exception_impl() to catch it ? or use BOOST_THROW_EXCEPTION to throw ? ////////// namespace boost { class thread_interrupted {}; } These function use [ throw thread_interrupted(); ] : this_thread ::interruption_point() // pthread / win32 this_thread::interruptible_wait() // win32 interruption_checker:: check_for_interruption()// pthread ///////////// // [Windows XP, VC++ 10, boost 1.46] #include <boost/thread.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <boost/thread/future.hpp> using namespace boost::posix_time; using namespace boost; int foo() { this_thread::sleep(seconds(1000)); return 0; } int main(int argc, char** argv) { boost::packaged_task<int> pt(&foo); boost::unique_future<int> fi = pt.get_future(); boost::thread task(std::move(pt)); // launch task on a thread task.interrupt(); try { int v = fi.get(); } catch (boost::exception& exc) { std::cerr << "ERROR: " << boost::diagnostic_information(exc) << std::endl; } } > > > > // unknown_exception////////////////// > > ERROR: Throw in function (unknown) > > Dynamic exception type: class boost::exception_detail::clone_impl<class > > boost::unknown_exception> > > std::exception::what: Unknown exception
Attachments (3)
Change History (11)
comment:1 by , 11 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
Summary: | [boost::thread] interrupt a future get boost::unknown_exception → interrupt a future get boost::unknown_exception |
by , 11 years ago
comment:2 by , 11 years ago
I have reached to compile the example with some variants.
It seems the problem comes from the fact that packaged_task catch every exception and store it to rethrow in the wait() function using boost::rethrow_exception. As thread_interrupted doesn't inherits from std/boost::exception the throw exception is unknown_exception.
if(rethrow && exception) { boost::rethrow_exception(exception); }
A solution could be to catch specifically thread_interrupted and store this fact.
When wait is called, a test if the thread has been interrupted is done so that the exception thread_interrupted is thrown. The single problem is that the this new exception doesn't contains from where the initial thread_interrupted was thrown.
See the attached patch for the complete solution.
comment:3 by , 11 years ago
There is also another patch that needs to be applied. See detail/move.hpp.diff file.
by , 11 years ago
Attachment: | detail_move.hpp.diff added |
---|
comment:4 by , 11 years ago
Type: | Bugs → Patches |
---|
comment:5 by , 11 years ago
Milestone: | To Be Determined → Boost 1.49.0 |
---|
comment:6 by , 11 years ago
Committed in trunk at revision [76543]. However the issue seems to be also on Windows platforms.
comment:7 by , 11 years ago
catch (boost::thread_interrupted& exc)
if the caller of fi.get() is a boost::thread and is interrupted, get() will throw thread_interrupted. but the future is interrupted now, not the caller. so I recommend get() throw a new class boost::future_interrupted use BOOST_THROW_EXCEPTION.
15 16 int main(int argc, char** argv) 17 { 18 boost::packaged_task<int> pt(&foo); 19 boost::unique_future<int> fi = pt.get_future(); 20 boost::thread task(boost::move(pt)); // launch task on a thread 21 22 task.interrupt(); 23 24 try 25 { 26 int v = fi.get(); 27 } 28 catch (boost::thread_interrupted& exc) 29 { 30 std::cout << "OK: " << std::endl; 31 return 0; 32 } 33 catch (boost::exception& exc) 34 { 35 std::cout << __LINE__ << " ERROR: " << boost::diagnostic_information(exc) << std::endl; 36 return 1; 37 } 38 catch (...) 39 { 40 std::cout << __LINE__ << " ERROR: " << std::endl; 41 return 2; 42 } 43 std::cout << __LINE__ << " ERROR: " << std::endl; 44 return 3; 45 }
comment:8 by , 10 years ago
Milestone: | Boost 1.49.0 → Boost 1.50.0 |
---|---|
Resolution: | → fixed |
Status: | assigned → closed |
Committed in release branch at [78543]
a possible solution