Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::future::wait_for() not time out?

The following code should terminate in much less than 1s in most cases:

#include <atomic>
#include <chrono>
#include <future>
#include <stop_token>
#include <thread>

using namespace std::chrono_literals;

std::atomic_bool p2_is_set{false};
std::promise<void> p2;

int main() {
    std::jthread set_p2([](const std::stop_token& token) {
        p2.set_value_at_thread_exit();
        p2_is_set = true;
        p2_is_set.notify_one();

        while (!token.stop_requested()) {
            std::this_thread::sleep_for(100ms);
        }
    });
    p2_is_set.wait(false);

    p2.get_future().wait_for(0ms); // this hangs
    set_p2.request_stop();
}

Unfortunately, it hangs in p2.get_future().wait_for(0ms) indefinitely, and I wonder why. I can reproduce the issue in MSVC 17.10 (https://godbolt.org/z/a3MfhWfTj), but not in other compilers.

Some additional debugging suggests p2.get_future().wait_for is waiting for an internal std::mutex - which implies the actual timeout value should not matter. That mutex is owned by the thread which called p2.set_value_at_thread_exit(). Specifically, p2._MyPromise._State._Assoc_state->_Mtx is unlocked before p2.set_value_at_thread_exit() and still locked after.

Knowing that, it is easy to see why this code seems to work but actually just crashes with an 0xc0000409 exit code:

#include <future>

int main() {
    std::promise<void> p;
    p.set_value_at_thread_exit();
    p.get_future().wait();
}
like image 527
bers Avatar asked Nov 22 '25 21:11

bers


1 Answers

This seems to be an MSVC/STL bug. Microsoft acknowledges as much in https://developercommunity.visualstudio.com/t/After-calling-std::promise::set_value_at/10205605. At the same time, fixing the bug would break ABI compatibility, which is why they are putting off a fix for now.

like image 147
bers Avatar answered Nov 24 '25 12:11

bers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!