See Another pattern for using the InitOnce functions
The performance can be improved since callback is not passed to Windows API, so no exception pointer calls needed, only call InitOnceComplete in a destructor (of a local class).
Looks like ABI breaking change.
@BillyONeal, didn't we make this change in the super-secret massively bitrotted not-yet-public ABI breaking branch? I can't otherwise imagine why InitOnceBeginInitialize/InitOnceComplete would be familiar to me.
Correct, I had already done this. Since we made the determination that this would be ABI breaking though we've gotten the satellite DLL tech, so this could probably be done without an ABI break using that. We could certainly do it with an opt-in switch that says "I only care about Vista+" and call aliases for InitOnceXxx directly.
I'd worry about the mixing scenarios - what if a once_flag is used by both old and new TUs? (I also wouldn't want to see opt-in switches in the headers for XP targeting - we can now assume that XP is never targeted by the headers, we just have to continue supporting it in the redist.)
I'd worry about the mixing scenarios - what if a
once_flagis used by both old and new TUs?
The contents and interpretation of once_flag don't change; both APIs take an INIT_ONCE. It would be possible for an "old" TU to call_once -> InitOnceExecuteOnce and a new TU to call_once -> InitOnceBeginInit/InitOnceComplete simultaneously.
XP would continue to be supported by the presence of _Execute_once in the redist until vNext.
What is the strategy if I see another more or less obvious ABI-breaking performance improvement?
Create an issue, or hold on with the assumption "this is probably already done"?
Please create an issue and note that it's ABI-breaking so we can tag it as vNext. We need to port things over by hand, so this will help make sure we don't forget anything critical.
It looks like the fallback spin thingy that __crtInitOnceExecuteOnce does instead of InitOnceExecuteOnce is stateless so I believe this can be done entirely in a satellite (or even the import lib), so I think it could be non-ABI-breaking with effort now that we have those techs.
The contents and interpretation of
once_flagdon't change; both APIs take anINIT_ONCE. It would be possible for an "old" TU tocall_once->InitOnceExecuteOnceand a new TU tocall_once->InitOnceBeginInit/InitOnceCompletesimultaneously.
Unfortunately, I don't see the proof that callback API and API without a callback have the same interpretation of INIT_ONCE. Apparently, there's no such information in the documentation.
I've addressed it with MicrosoftDocs/win32#308 , now is documented here:
https://docs.microsoft.com/en-us/windows/win32/sync/one-time-initialization#synchronous-one-time-initialization
Most helpful comment
The contents and interpretation of
once_flagdon't change; both APIs take anINIT_ONCE. It would be possible for an "old" TU tocall_once->InitOnceExecuteOnceand a new TU tocall_once->InitOnceBeginInit/InitOnceCompletesimultaneously.XP would continue to be supported by the presence of
_Execute_oncein the redist until vNext.