1

The documentation for concurrency::task says:

When a task object is assigned to a new variable, the behavior is that of std::shared_ptr; in other words, both objects represent the same underlying task.

So when the task is destructed, and no other references remain, what happens to the underlying task?

ppltasks.h genuinely does seem to implement this with a shared_ptr:

template <typename _ReturnType>
struct _Task_ptr {
  typedef ::std::shared_ptr<_Task_impl<_ReturnType>> _Type;
  static _Type _Make(_CancellationTokenState* _Ct,
                     scheduler_ptr _Scheduler_arg) {
    return ::std::make_shared<_Task_impl<_ReturnType>>(_Ct, _Scheduler_arg);
  }
};

But what does that mean for usage? Are unnamed temporary tasks OK to use in general? Is this code safe? It seems to continue the task and print done after 1 second, even though the task is destructed by the time the print comes around. Is this UB?

#include <ppltasks.h>

#include <chrono>
#include <thread>

using namespace std::chrono;
using namespace concurrency;
using std::this_thread::sleep_for;

int main() {
  {
    auto t = create_task([&] {
      sleep_for(1s);
      std::printf("done\n");
    });
  }

  std::printf("sleeping for 2 seconds\n");

  sleep_for(2s);

  return 0;
}
MHebes
  • 2,290
  • 1
  • 16
  • 29
  • As far as I can tell, a destructed task object basically works like a detached thread. Safe, as long as all its captured references remain valid, and killed/cleaned up by the OS when main() exits. – MHebes May 30 '23 at 19:43

0 Answers0