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