mercredi 30 mars 2016

What is the standard mandated behavior of std::promise's destructor after calling set_value_at_thread_exit?

If you destroy an std::promise whose shared state is not yet ready, but for which someone has called set_value_at_thread_exit (and that thread has not yet exited), what is the expected result?

As best I can tell, the destructor for the promise should store a future_error exception (with code broken_promise) into the shared state. However, this does not appear to be the behavior for GNU/libstdc++, which will yield the stored value (and not throw an exception) on a call to the future's get().

I've come to my conclusion based on my reading of cppreference's descriptions for std::promise::set_value_at_thread_exit:

Stores the value into the shared state without making the state ready immediately. The state is made ready when the current thread exits, after all variables with thread-local storage duration have been destroyed.

and for std::promise::~promise

Abandons the shared state:

  • if the shared state is ready, releases it.
  • if the shared state is not ready, stores an exception object of type std::future_error with an error condition std::future_errc::broken_promise, makes the shared state ready and releases it.

For example code:

#include <future>

void foo(std::promise<int> p)
{
  p.set_value_at_thread_exit(42);
  // p is destroyed here
}

int main()
{       
  std::promise<int> p;
  std::future<int>  f = p.get_future();
  std::thread t(foo, std::move(p));
  t.join();
  (void)f.get(); // Throw future_error or return 42 ?
}

Aucun commentaire:

Enregistrer un commentaire