Search code examples
c++multithreadingstdc++23

Is std::move_only_function thread safe?


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.


Solution

  • 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.