Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can std::call_once be reset?

I wrote a function a while ago, based on Unreal Engine 4's blueprint implementation, that invokes a callable exactly once until it is reset:

template<typename Callable>
void DoOnce(Callable&& f, bool reset = false, bool start_closed = false) noexcept {
    static bool once = start_closed;
    if(!once) {
        once = true;
        std::invoke(f);
    }
    if(reset) {
        once = false;
    }
}

Today I learned std::call_once exists, works across threads, works with callables that have arguments, tests for exception-safety, and basically wraps around std::invoke like mine does (the MSVC implementation at least).

That sounds great and, where possible, I prefer calling a pre-existing function over writing my own anyway.

Like Unreal's documentaion suggests, there are times that I may need to invoke the callable again by resetting the internal flag; can std::call_once be reset in order to allow the underlying callable to be invoked again?

like image 555
Casey Avatar asked Aug 03 '26 11:08

Casey


2 Answers

The standard isn't kidding when they call it "once_flag". It's a flag that only gets set once.

You can of course call the function multiple times, with different once-flag objects. But to do this properly, you need to hand each thread that might attempt to call it the new once-flag object. It can't just be a global or static object somewhere; you have to actually marshal each new invocation out to all of the threads that want to call it.

like image 188
Nicol Bolas Avatar answered Aug 07 '26 12:08

Nicol Bolas


Well, there is hack for that. You could have something like:

using namespace std;

auto flag = make_unique<once_flag>();

void f(int x) {
    cout << x << " f called\n";
}

int main()
{
    call_once(*flag, f, 5);
    call_once(*flag, f, 15); // This one won't be called
    flag = make_unique<once_flag>(); // "resets" the flag
    call_once(*flag, f, 15); // This one will be called
    return 0;
}
like image 23
vmp Avatar answered Aug 07 '26 14:08

vmp



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!