From abd749f1f41f4144f65ecd95039fa17a5680537c Mon Sep 17 00:00:00 2001 From: "Matthias C. M. Troffaes" Date: Tue, 22 Jun 2021 15:03:54 +0100 Subject: [PATCH 1/3] Fix TLS segfault on static builds. --- avs_core/core/avisynth.cpp | 14 +++++++------- avs_core/core/internal.h | 18 ++++++++++++++++++ avs_core/core/main.cpp | 15 +-------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/avs_core/core/avisynth.cpp b/avs_core/core/avisynth.cpp index 153bd9b015..f57c688745 100644 --- a/avs_core/core/avisynth.cpp +++ b/avs_core/core/avisynth.cpp @@ -1131,7 +1131,7 @@ struct ScriptEnvironmentTLS // this is a work-around for that. #ifdef AVS_WINDOWS # ifdef XP_TLS -extern DWORD dwTlsIndex; +extern _TLS _tls; # else // does not work on XP when DLL is dynamic loaded. see dwTlsIndex instead __declspec(thread) ScriptEnvironmentTLS* g_TLS = nullptr; @@ -1159,14 +1159,14 @@ class ThreadScriptEnvironment : public InternalEnvironment if (thread_id != 0) { // thread pool thread #ifdef XP_TLS - ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(dwTlsIndex)); + ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(_tls.dwTlsIndex)); #endif if (g_TLS != nullptr) { ThrowError("Detected multiple ScriptEnvironmentTLSs for a single thread"); } g_TLS = &myTLS; #ifdef XP_TLS - if (!TlsSetValue(dwTlsIndex, g_TLS)) { + if (!TlsSetValue(_tls.dwTlsIndex, g_TLS)) { ThrowError("Could not store thread local value for ScriptEnvironmentTLS"); } #endif @@ -1183,7 +1183,7 @@ class ThreadScriptEnvironment : public InternalEnvironment #ifdef XP_TLS // a ? : b, evaluate 'a' only once #define IFNULL(a, b) ([&](){ auto val = (a); return ((val) == nullptr ? (b) : (val)); }()) -#define DISPATCH(name) IFNULL((ScriptEnvironmentTLS*)(TlsGetValue(dwTlsIndex)), coreTLS)->name +#define DISPATCH(name) IFNULL((ScriptEnvironmentTLS*)(TlsGetValue(_tls.dwTlsIndex)), coreTLS)->name #else #define DISPATCH(name) (g_TLS ? g_TLS : coreTLS)->name #endif @@ -1575,7 +1575,7 @@ class ThreadScriptEnvironment : public InternalEnvironment bool is_runtime = true; #ifdef XP_TLS - ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(dwTlsIndex)); + ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(_tls.dwTlsIndex)); #endif if (g_TLS == nullptr) { // not called by thread if (GetFrameRecursiveCount() == 0) { // not called by GetFrame @@ -1741,7 +1741,7 @@ class ThreadScriptEnvironment : public InternalEnvironment void __stdcall DeleteScriptEnvironment() { #ifdef XP_TLS - ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(dwTlsIndex)); + ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(_tls.dwTlsIndex)); #endif if (g_TLS != nullptr) { ThrowError("Cannot delete environment from a TLS proxy."); @@ -2220,7 +2220,7 @@ ScriptEnvironment::ScriptEnvironment() nMaxFilterInstances(1) { #ifdef XP_TLS - if(dwTlsIndex == 0) + if(_tls.dwTlsIndex == 0) throw("ScriptEnvironment: TlsAlloc failed on DLL load"); #endif diff --git a/avs_core/core/internal.h b/avs_core/core/internal.h index cb015d02a8..d0c32f340d 100644 --- a/avs_core/core/internal.h +++ b/avs_core/core/internal.h @@ -311,4 +311,22 @@ class GlobalVarFrame } }; +#ifdef XP_TLS +#include +struct _TLS { + DWORD dwTlsIndex; + _TLS() : dwTlsIndex(0) { + if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) + throw("TlsAlloc failed"); + _RPT1(0, "TlsAlloc: dwTlsIndex=0x%x\n", dwTlsIndex); + + } + ~_TLS() { + _RPT1(0, "TlsFree: dwTlsIndex=0x%x\n", dwTlsIndex); + TlsFree(dwTlsIndex); + dwTlsIndex = 0; + } +}; +#endif + #endif // __Internal_H__ diff --git a/avs_core/core/main.cpp b/avs_core/core/main.cpp index 7fc28a56ae..55ddc2648b 100644 --- a/avs_core/core/main.cpp +++ b/avs_core/core/main.cpp @@ -122,7 +122,7 @@ void ReportMe(const char * msg, ...) { static long gRefCnt=0; #ifdef XP_TLS -DWORD dwTlsIndex = 0; +_TLS _tls; #endif extern "C" const GUID CLSID_CAVIFileSynth // {E6D6B700-124D-11D4-86F3-DB80AFD98778} @@ -280,19 +280,6 @@ BOOL APIENTRY DllMain(HANDLE hModule, ULONG ulReason, LPVOID lpReserved) { _RPT4(0,"DllMain: hModule=0x%08x, ulReason=%x, lpReserved=0x%08x, gRefCnt = %ld\n", hModule, ulReason, lpReserved, gRefCnt); -#ifdef XP_TLS - if (ulReason == DLL_PROCESS_ATTACH) { - if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) - throw("Avisynth DLL load: TlsAlloc failed"); - _RPT1(0, "DllMain: TlsAlloc: dwTlsIndex=0x%x\n", dwTlsIndex); - } - else if (ulReason == DLL_PROCESS_DETACH) { - _RPT1(0, "DllMain: TlsFree: dwTlsIndex=0x%x\n", dwTlsIndex); - TlsFree(dwTlsIndex); - dwTlsIndex = 0; - } -#endif - return TRUE; } From f76cf5ae7073115b8a66b8f7efd24a55c2b573bb Mon Sep 17 00:00:00 2001 From: "Matthias C. M. Troffaes" Date: Tue, 22 Jun 2021 16:51:03 +0100 Subject: [PATCH 2/3] Only define XP_TLS if _USING_V110_SDK71_ is defined (i.e. when targetting the v141_xp platform). --- avs_core/include/avs/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avs_core/include/avs/config.h b/avs_core/include/avs/config.h index d78ddc4df1..ff5c727166 100644 --- a/avs_core/include/avs/config.h +++ b/avs_core/include/avs/config.h @@ -149,7 +149,7 @@ #define NEW_AVSVALUE #endif -#if defined(AVS_WINDOWS) +#if defined(AVS_WINDOWS) && defined(_USING_V110_SDK71_) // Windows XP does not have proper initialization for // thread local variables. // Use workaround instead __declspec(thread) From 0fda66cf266b1c1b8806dcbb2aea221c2839b4e1 Mon Sep 17 00:00:00 2001 From: "Matthias C. M. Troffaes" Date: Mon, 4 Jul 2022 17:01:55 +0100 Subject: [PATCH 3/3] Fix for accidental addition after merge. --- avs_core/include/avs/config.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/avs_core/include/avs/config.h b/avs_core/include/avs/config.h index d1ff8b1583..bdabf17f29 100644 --- a/avs_core/include/avs/config.h +++ b/avs_core/include/avs/config.h @@ -150,12 +150,6 @@ #endif -#if defined(AVS_POSIX) -#define NEW_AVSVALUE -#else -#define NEW_AVSVALUE -#endif - #if defined(AVS_WINDOWS) && defined(_USING_V110_SDK71_) // Windows XP does not have proper initialization for // thread local variables.