mercredi 7 août 2019

Is notification of threads guaranteed for std::call_once after exceptional call

The standard example for std::call_once on cppreference.com describes the behavior for exceptional calls that way, that to my understanding other threads wait for the first entering the std::call_once and in case of an exception the next thread will try to execute the std::call_once. While online compilers confirm this behavior, I cannot reproduce it locally. For the minimal example

#include <iostream>
#include <thread>
#include <mutex>

std::once_flag flag;

void may_throw_function(bool do_throw)
{
  if (do_throw) {
    std::cout << "throw: call_once will retry\n";
    throw std::exception();
  }
  std::cout << "Didn't throw, call_once will not attempt again\n";
}

void do_once(bool do_throw)
{
  try {
    std::call_once(flag, may_throw_function, do_throw);
  }
  catch (...) {}
}

int main()
{
    std::thread t1(do_once, true);
    std::thread t2(do_once, true);
    std::thread t3(do_once, false);
    std::thread t4(do_once, true);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
}

copied from cppreference.com the execution is stuck after the first throw and runs forever

Compilation is done with g++-5 -std=c++14 source.cpp -pthread (version g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609) or clang++-6.0 source.cpp -pthread (version clang version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final)).

Putting more output into the code shows, that all threads are started, but only the threads that throws first ever ends. All others seems to wait before the std::call_once statement. Hence my question: Is the notification of threads that are waiting for the first thread to finish guaranteed?

Aucun commentaire:

Enregistrer un commentaire