I have my own thread class that is intended to help safely manage exceptions. It looks like this: (skipped other constructors and mutexes for simplicity)
class ExceptThread
: public std::thread {
public:
template<typename Func, typename... Args>
ExceptThread(Func&& f, Args&&... args)
: std::thread([] (Args&&... args) {
try {
return f(args...);
} catch(...) {
exc = std::current_exception();
}
}, args...) { }
// skipped other constructors etc.
//...
void check() {
if(exc) {
std::exception_ptr tmp = exc;
exc = nullptr;
std::rethrow_exception(tmp);
}
}
private:
std::exception_ptr exc;
};
This class means to be used like:
ExceptThread et([] { std::this_thread::sleep_for(5s); throw std::runtime_error("Ugly exception"); });
try {
while(/*...*/) {
// main loop
et.check();
}
} catch(std::exception& e) {
// do sth
}
Problem:
When thread throws exception it gets catched in catch(...)
and saved to exc
, everything is fine. But when execution goes further std::terminate
is called just like exception wasn't caught. I also tried to pause the child thread (e.g Sleep(INFINITE)
) after catching an exception but std::terminate()
gets called while detaching the thread in std::thread::~thread()
during stack unwinding in main thread. How can I prevent system of doing this?
Platform: MSVC