How to tell std::future if std::promise exist in C++?

714 views Asked by At

I create a std::packaged_task, push it to a std::list and return its std::future to users, like this:

future_t emplace(...)
{
    //...
    auto task = std::make_shared<std::packaged_task<return_t()>>(
                std::bind(std::forward<F>(f), std::forward<Args>(args)...));
    tasks.emplace_back(task);
    std::future<return_t> result = task->get_future();
    
    //...
    return result;
}

In another thread, we may clear the tasks list at anytime:

// another thread
std::list<task_t> temp_{};
tasks.swap(temp_);

But users may call std::future still:

auto result = emplace(...);
// do something and the tasks list has been clear in anthor thread
auto ret = result.get();

Get a exception error as std::promise has been destroyed:

C++ exception with description "std::future_error: Broken promise" thrown in the test body.

I can use a exception expression to avoid the program broken:

try
{
    auto ret = result.get();
}
catch (...)
{
}

Can I avoid std::future_error without exception expression? My question is: Is there any other method to detect if the std::promise exist?

1

There are 1 answers

0
Nimrod On

I'm afraid there is no direct way to detect if the promise still exists. If you must do that, you may have to do some additional work to keep the state of the task(or the corresponding future), which is more complicated than the current solution. All futures are by default invalid. Whenever you execute the task, you mark the future is valid. Whenever you're to get a result through a future, check if it's valid.

Notice: you have to handle the synchronization of this state since this state is shared between different threads. That sounds wired, right? You're going to share another data outside the pairwise promise and future. I don't recommend and don't think it's necessary to do so.

When you're using std::promise and std::future, all exceptions should be handled in the std::future::get.