Setting exeption for promise causes abort call - c++

I have a throwing function:
void calculateValuesThrowing(std::promise<int>&& pr, int a, int b)
{
try
{
auto timeout = std::chrono::seconds(5);
logInfo("Calculating value...");
std::this_thread::sleep_for(timeout);
if (a == b)
{
throw std::runtime_error("a cannot equal b");
}
pr.set_value(a + b);
}
catch(std::exception& exc)
{
pr.set_exception(std::current_exception()); // ok, jump here right after the "throw" above
}
}
and I call it like that:
somewhere in main() function:
try
{
std::promise<int> promise;
auto future = promise.get_future();
std::thread th(calculateValuesThrowing, std::move(promise), 10, 10);
auto result = future.get();
th.join();
}
catch(std::exception& exc)
{
std::cout << "Error:" << exc.what(); // never get there
}
I expect an exception of calculateValuesThrowing will be "rethrown" so that I could process it in main's catch(), but right after calculateValuesThrowing finishes working I get abort().
What am I doing wrong?

When future.get() throws, th.join() is never invoked so th goes out of scope while the thread is still active. This terminates the program.
Try [sic] something like this instead:
std::promise<int> promise;
auto future = promise.get_future();
std::thread th(calculateValuesThrowing, std::move(promise), 10, 10);
try
{
auto result = future.get();
}
catch(std::exception& exc)
{
std::cout << "Error:" << exc.what(); // never get there
}
th.join();
Of course, now you can't use result outside of the try, but that was the case anyway. I don't have enough information about how you use it to suggest a concrete fix for that.

Related

Receive async exception directly

class ClassA
{
void running()
{
int count = 0;
m_worker_stop.store(true);
while (m_worker_stop.load() == false)
{
count++;
if (count == 10)
{
// Make exception
std::vector v(100000000000);
}
}
}
void start()
{
m_worker = std::async(std::launch::async, &ClassA::running, this);
}
void stop()
{
m_worker_stop.store(true);
if (m_worker.valid())
m_worker.get(); // catch exception in this point
}
std::future<void> m_worker;
std::atomic_bool m_worker_stop = { false };
}
class Main // this is single-ton Main class
{
...
void running()
{
try {
m_classA->start();
// Wait for external signal(ex. SIGINT, SIGTERM, ..)
while (true) { // signal check }
m_classA->stop();
}
catch(std::exception& e) {
// re-create throwed object
}
catch(...) {
// re-create throwed object
}
}
}
int main()
{
Manager::getInstance()::running();
return 0;
}
Hello, everyone.
The approximate structure of the program is as above.
In fact, I have not only classA but also many other objects such as B, C, and D.
(start() and stop() function is simillar !)
An exception was raised using std::vector v(1000000..)
However, it became a catch when stop() was activated.
What I actually want is to delete the classA object and re-create it if an exception occurs.
So I need to catch directly when exception was occured.
In this case, is any idea to get exception without wait for signals?
Here is one way of achieving the effect you want:
class Main // this is single-ton Main class
{
...
void running()
{
for (size_t i = 0; i < max_tries; ++i)
{
try {
m_classA->start();
// Wait for external signal(ex. SIGINT, SIGTERM, ..)
while (true) {
// signal check ...
}
m_classA->stop();
// path to happy ending :)
LOG("Main::running(): Operation successful.",
return;
}
catch(std::exception& e) {
LOG("Main::running(): Exception caught: message:\"{}\"", e.what());
}
catch(...) {
LOG("Main::running(): Unspecified exception caught, aborting.");
return; // Example of 'unrecoverable error'
}
// this part is only executed after an exception.
m_classA->shut_down(); // if you need some special shut down after an error.
m_classA.clear(); // this is redundant, but explicit (optional)
m_classA = MakeMeAnA(); // call our favorite A construction method.
}
// path to total failure :(
LOG("Main::running(): Exiting after {} failed attempts", max_tries);
}
private:
static constexpr size_t max_tries = 3;
};

C++ catch error and exit the function

I use try{} catch(){} to handle errors in a function which return a template type.
T get (int iOffset) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return a;
}
The function would first call checkIndex to check whether the input is out of range and throw an error if so.
However, I don't want the outside get return any value if checkIndex throws an error, because the returned value may be used by other functions or printed out incorrectly. If I put a return in the catch block, I don't know what to return since it's a template. If I don't, the codes following the catch block will still get executed and therefore return a value.
Is there any way to do that? I'm new to C++ and wondering how people usually do the error handling in this condition? THanks!
However, I don't want the outside get return any value if checkIndex throws an error, because the returned value may be used by other functions or printed out incorrectly.
You can always re-throw the exception after logging
T get (int iOffset) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
throw; // Just re-throw the exception
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return a;
}
You can also use optional for this situation. One of idea of this construct was to indicate that value cannot be set correctly because of some mistakes.
std::optional< T > get (int iOffset ) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
return std::optional< T >();
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return return std::optional< T >( a );
}
Using of such function can look like this:
auto result = get( someOffset );
if( result )
{
// correct, processing result
}
One of the easiest way is first to decide: What exactly should your get() return if it cannot return the 'proper' value?
In many cases it is just 0, or -1, or some other special value.
And then the code become very simple:
T get (int iOffset) const
{
T a;
try {
checkIndex(iOffset);
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
a = m_ptBuff[index];
}
catch (char const* msg) {
a = special_value_for_errors;
std::cout << msg << std::endl;
}
return a;
}

How to stop a async evaluating function on timeout?

say we have a simple async call we want to kill/terminate/eliminate on timeout
// future::wait_for
#include <iostream> // std::cout
#include <future> // std::async, std::future
#include <chrono> // std::chrono::milliseconds
// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
for (int i=2; i<x; ++i) if (x%i==0) return false;
return true;
}
int main ()
{
// call function asynchronously:
std::future<bool> fut = std::async (is_prime,700020007);
// do something while waiting for function to set future:
std::cout << "checking, please wait";
std::chrono::milliseconds span (100);
while (fut.wait_for(span)==std::future_status::timeout)
std::cout << '.';
bool x = fut.get();
std::cout << "\n700020007 " << (x?"is":"is not") << " prime.\n";
return 0;
}
we want to kill it as soon as first timeout happens. Cant find a method in future.
The closest I could find to stop a running task was std::packaged_task reset method yet it does not say if it can interrupt a running task. So how one kills a task running asyncrinusly not using boost thread or other non stl libraries?
It's not possible to stop a std::async out of the box... However, You can do this, pass a bool to terminate the is_prime method and throw an exception if there is a timeout:
// future::wait_for
#include <iostream> // std::cout
#include <future> // std::async, std::future
#include <chrono> // std::chrono::milliseconds
// A non-optimized way of checking for prime numbers:
bool is_prime(int x, std::atomic_bool & run) {
for (int i = 2; i < x && run; ++i)
{
if (x%i == 0) return false;
}
if (!run)
{
throw std::runtime_error("timed out!");
}
return true;
}
int main()
{
// Call function asynchronously:
std::atomic_bool run;
run = true;
std::future<bool> fut = std::async(is_prime, 700020007, std::ref(run));
// Do something while waiting for function to set future:
std::cout << "checking, please wait";
std::chrono::milliseconds span(100);
while (fut.wait_for(span) == std::future_status::timeout)
{
std::cout << '.';
run = false;
}
try
{
bool x = fut.get();
std::cout << "\n700020007 " << (x ? "is" : "is not") << " prime.\n";
}
catch (const std::runtime_error & ex)
{
// Handle timeout here
}
return 0;
}
Why being able to stop thread is bad.
Stopping threads at an arbitrary point is dangerous and will lead to resource leaks, where resources being pointers, handles to files and folders, and other things the program should do.
When killing a thread, the thread may or may not be doing work. Whatever it was doing, it won’t get to complete and any variables successfully created will not get their destructors called because there is no thread to run them on.
I have outlined some of the issues here.
I think its not possible to safely interrupt running cycle from outside of cycle itself, so STL doesn't provide such a functionality. Of course, one could try to kill running thread, but it's not safe as may lead to resource leaking.
You can check for timeout inside is_prime function and return from it if timeout happens. Or you can try to pass a reference to std::atomic<bool> to is_prime and check its value each iteration. Then, when timeout happens you change the value of the atomic in the main so is_prime returns.

Error checking on many function calls

Sometimes when I am programming in C++/C I end up calling the same function multiple times and I was wondering what is the most efficient way to check for errors for all of those calls? Using if else statements take up a lot of code and look ugly. I have come up with my own way of checking for errors, perhaps there is a better way that I should use.
int errs[5] = {0};
errs[0] = functiona(...);
errs[1] = functiona(...);
...
errs[5] = functiona(...);
for (int i = 0; i < 5; i++)
{
if (err[i] == 0)
MAYDAY!_wehaveanerror();
}
Note: I understand that using try and catch might be better for C++ as it would solve this problem by throwing an exception on the first error, but the problem with that is that it is not compatible with a lot of functions that return error codes such as the Windows API. Thanks!
You could write some pseudo-C++ like this:
struct my_exception : public std::exception {
my_exception(int); /* ... */ };
int main()
{
try
{
int e;
if ((e = function()) != SUCCESS) { throw my_exception(e); }
if ((e = function()) != SUCCESS) { throw my_exception(e); }
if ((e = function()) != SUCCESS) { throw my_exception(e); }
}
catch (my_exception & e)
{
std::cerr << "Something went wrong: " << e.what() << "\n";
}
}
If...IF the function has a chance to throw a different error you should also add a catch all.
struct my_exception : public std::exception {
my_exception(int); /* ... */ };
int main()
{
try
{
int e;
if ((e = function()) != SUCCESS) { throw my_exception(e); }
if ((e = function()) != SUCCESS) { throw my_exception(e); }
if ((e = function()) != SUCCESS) { throw my_exception(e); }
}
catch (my_exception & e)
{
std::cerr << "Something went wrong: " << e.what() << "\n";
}
catch (...)
{
//Error Checking
}
}
What about handling the checking in a function?
void my_function() {
if (!create_window())
throw Error("Failed to create window");
}
int main() {
try {
my_function();
} catch (const Error& e) {
cout << e.msg << endl;
} catch (...) {
cout << "Unknown exception caught\n"
}
return 0;
}
If you're calling the same function over and over again, the most succinct way might be to use a macro. I would suggest something like:
#define CHECKERROR(x) if(x == 0) wehaveanerror()
CHECKERROR(function(...));
CHECKERROR(function(...));
Obviously, this macro would be very specific to the particular function and error handler involved, so it may be prudent to undef it after those calls.
Doing it more old-school, but keeping w/ the original error response but responding as soon as an error occurs w/o looking ugly:
#define callcheck(r) if ((r)==0) MAYDAY!_wehaveanerror()
callcheck(functiona(...));
callcheck(functiona(...));
...

How to get the exception reported to boost::future?

If I use Boost futures, and the future reports true to has_exception(), is there any way to retrieve that exception? For example, here is the following code:
int do_something() {
...
throw some_exception();
...
}
...
boost::packaged_task task(do_something);
boost::unique_future<int> fi=task.get_future();
boost::thread thread(boost::move(task));
fi.wait();
if (fi.has_exception()) {
boost::rethrow_exception(?????);
}
...
The question is, what should be put in the place of "?????"?
According to http://groups.google.com/group/boost-list/browse_thread/thread/1340bf8190eec9d9?fwc=2, you need to do this instead:
#include <boost/throw_exception.hpp>
int do_something() {
...
BOOST_THROW_EXCEPTION(some_exception());
...
}
...
try
{
boost::packaged_task task(do_something);
boost::unique_future<int> fi=task.get_future();
boost::thread thread(boost::move(task));
int answer = fi.get();
}
catch(const some_exception&)
{ cout<< "caught some_exception" << endl;}
catch(const std::exception& err)
{/*....*/}
...