From 1834d17e5f90bf71d7bfb1eda773b6b69528264c Mon Sep 17 00:00:00 2001 From: Jordan Rabet Date: Thu, 24 Sep 2020 17:09:24 -0700 Subject: [PATCH] XFG: made _Execute_once XFG-compatible. --- stl/src/xonce.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/stl/src/xonce.cpp b/stl/src/xonce.cpp index 5c6a5f9c2f9..5815b531471 100644 --- a/stl/src/xonce.cpp +++ b/stl/src/xonce.cpp @@ -13,8 +13,17 @@ _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Execute_once( once_flag& _Flag, _Execute_once_fp_t _Callback, void* _Pv) noexcept { // wrap Win32 InitOnceExecuteOnce() static_assert(sizeof(_Flag._Opaque) == sizeof(INIT_ONCE), "invalid size"); + // _Execute_once_fp_t and PINIT_ONCE_FN differ in type signature, therefore + // we introduce _Xfg_trampoline which has PINIT_ONCE_FN's type signature and + // calls into _Callback as an _Execute_once_fp_t for XFG compatibility. + + PINIT_ONCE_FN _Xfg_trampoline = [](PINIT_ONCE _InitOnce, PVOID _Parameter, PVOID* _Context) { + const auto _Callback = reinterpret_cast<_Execute_once_fp_t>(_Context); + return static_cast(_Callback(_InitOnce, _Parameter, nullptr)); + }; + return __crtInitOnceExecuteOnce( - reinterpret_cast(&_Flag._Opaque), reinterpret_cast(_Callback), _Pv, nullptr); + reinterpret_cast(&_Flag._Opaque), _Xfg_trampoline, _Pv, reinterpret_cast(_Callback)); } [[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL