From b9cb252b33b0b026acc0af48ee63e2a8d5c5ac6d Mon Sep 17 00:00:00 2001 From: mingkuang Date: Fri, 20 Sep 2024 00:18:34 +0800 Subject: [PATCH] =?UTF-8?q?Opt,=20=E6=96=B0=E5=A2=9E=5F=5FYY=5FThunks=5FDi?= =?UTF-8?q?sable=5FRreload=5FDlls=E5=BC=B1=E7=AC=A6=E5=8F=B7=EF=BC=8C?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E9=A2=84=E5=8A=A0=E8=BD=BD=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Build.cmd | 2 +- src/Thunks/YY_Thunks.h | 28 +++++++++++++++++++++------- src/YY-Thunks.UnitTest/weak.c | 2 ++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/Build.cmd b/src/Build.cmd index 58d20a7..392ba08 100644 --- a/src/Build.cmd +++ b/src/Build.cmd @@ -140,7 +140,7 @@ goto:eof :: FixObj "XXX\YY_Thunks_for_Vista.obj" 1.def+2.def :FixObj -LibMaker.exe FixObj %1 /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__acrt_atexit_table=%PointType% /WeakExternFix:__pfnDllMainCRTStartupForYY_Thunks=%PointType% +LibMaker.exe FixObj %1 /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__acrt_atexit_table=%PointType% /WeakExternFix:__pfnDllMainCRTStartupForYY_Thunks=%PointType% /WeakExternFix:__YY_Thunks_Disable_Rreload_Dlls=4 if %ErrorLevel% NEQ 0 exit /b %ErrorLevel% if "%2"=="" goto:eof set DEF_FILES=%2 diff --git a/src/Thunks/YY_Thunks.h b/src/Thunks/YY_Thunks.h index 28d4ff7..1060eca 100644 --- a/src/Thunks/YY_Thunks.h +++ b/src/Thunks/YY_Thunks.h @@ -104,6 +104,17 @@ else */ EXTERN_C const UINT64 __YY_Thunks_Installed = YY_Thunks_Target; +/* +导出一个外部弱符号,指示当前是否关闭DLL预载(默认开启DLL预载)。 +警告:关闭DLL预载虽然可以提升初始化速度,但是这可能带来死锁问题。目前已知的有: + 1. locale锁/LoadDll锁交叉持锁产生死锁(https://github.com/Chuyu-Team/YY-Thunks/issues/7) + 2. thread safe init锁/LoadDll锁交叉持锁产生死锁 + +// 如果需要关闭DLL预载,那么再任意位置定义如下变量即可: +EXTERN_C const BOOL __YY_Thunks_Disable_Rreload_Dlls = TRUE; +*/ +EXTERN_C extern BOOL __YY_Thunks_Disable_Rreload_Dlls /* = FALSE*/; + // 从DllMain缓存RtlDllShutdownInProgress状态,规避退出时调用RtlDllShutdownInProgress。 // 0:缓存无效 // 1:模块正常卸载 @@ -642,14 +653,17 @@ static ThunksInitStatus __cdecl _YY_initialize_winapi_thunks(ThunksInitStatus _s // 后续过程已经可以线程安全执行了,所以我们立即解锁,避免其他线程过于长时间的等待 InterlockedExchange((volatile LONG*)&s_eThunksStatus, LONG(_sInitStatus)); - /* - * https://github.com/Chuyu-Team/YY-Thunks/issues/7 - * 为了避免 try_get 系列函数竞争 DLL load锁,因此我们将所有被Thunk的API都预先加载完毕。 - */ - for (auto p = (InitFunType*)__YY_THUNKS_INIT_FUN_START; p != (InitFunType*)__YY_THUNKS_INIT_FUN_END; ++p) + if (!__YY_Thunks_Disable_Rreload_Dlls) { - if (auto pInitFun = *p) - pInitFun(); + /* + * https://github.com/Chuyu-Team/YY-Thunks/issues/7 + * 为了避免 try_get 系列函数竞争 DLL load锁,因此我们将所有被Thunk的API都预先加载完毕。 + */ + for (auto p = (InitFunType*)__YY_THUNKS_INIT_FUN_START; p != (InitFunType*)__YY_THUNKS_INIT_FUN_END; ++p) + { + if (auto pInitFun = *p) + pInitFun(); + } } return _sInitStatus; diff --git a/src/YY-Thunks.UnitTest/weak.c b/src/YY-Thunks.UnitTest/weak.c index 0b33576..d46c421 100644 --- a/src/YY-Thunks.UnitTest/weak.c +++ b/src/YY-Thunks.UnitTest/weak.c @@ -2,3 +2,5 @@ const void* __acrt_atexit_table; const void* __pfnDllMainCRTStartupForYY_Thunks; + +const void* __YY_Thunks_Disable_Rreload_Dlls;