c++c++11stdthreadpackaged-task

Is it safe to never retrieve the result of a std::future from a std::packaged_task?


Is it safe to create a std::future from a std::packaged_task, which executes on a separate thread, but not always retrieve its result?

#include <future>
#include <thread>

class Result {
  Result() {}
  ~Result() {}
};

void foo() {
  std::packaged_task<Result()> task(..);
  auto future = task.get_future();
  std::thread thread(std::move(task), ...);
  thread.detach();
  if (future.wait_for(std::chrono::milliseconds(timeout_ms)) == std::future_status::ready) {
    auto result = future.get();  <--- Task didn't take too long, retrieve future result
    ...
  }
}  <--- Task is taking too long, just abort and never call future.get()

It seems to work on Clang / libc++: ~Result() is called on the returned result by the std::packaged_task wether or not get() is eventually called on the std::future, but since I couldn't find anything in the C++ docs about this usage pattern, I'd like to make sure it's officially supported.


Solution

  • It depends.... on what you consider as safe for your program.
    For the context you have shown, it's safe as in:

    these actions will not block for the shared state to become ready, except that it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state.

    Now, what if the Result class was holding a non-owning memory (for whatever reason) or some other resource which needs to be manually freed up. In that case, the correctness of your code becomes questionable. A better thing to do would be to dispatch it to some background thread for slow moving tasks.