C++ Multithreading – How to Determine if std::move_only_function is Thread Safe

c++c++23multithreadingstd

Is it safe to call a std::move_only_function object in one thread and replace the function it points to in another thread?

My code:

#include <future>
#include <functional>

int main() {
    std::move_only_function<void()> fn = []{};

    auto future1 = std::async(std::launch::async, [&]{ fn(); });
    auto future2 = std::async(std::launch::async, [&]{ fn = []{}; });

    future1.get();
    future2.get();
}

I don't care if the old or the new function is called. Also I know that fn always holds a valid function.

Best Answer

No it is not safe.
The assignment operator (std::move_only_function::operator=) is not guaranteed to be atomic.
Therefore you can have a context switch in the middle of it, leaving the std::move_only_function object in an invalid state which the other thread will attempt to invoke leading to undefined-behavior.