Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TLS segfault in windows static build. #222

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions avs_core/core/avisynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ struct ScriptEnvironmentTLS
// this is a work-around for that.
#if defined(AVS_WINDOWS) && !defined(__GNUC__)
# 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;
Expand Down Expand Up @@ -1195,14 +1195,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
Expand All @@ -1219,7 +1219,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
Expand Down Expand Up @@ -1616,7 +1616,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
Expand Down Expand Up @@ -1778,7 +1778,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.");
Expand Down Expand Up @@ -2261,7 +2261,7 @@ ScriptEnvironment::ScriptEnvironment()
cacheMode(CACHE_DEFAULT)
{
#ifdef XP_TLS
if(dwTlsIndex == 0)
if(_tls.dwTlsIndex == 0)
throw("ScriptEnvironment: TlsAlloc failed on DLL load");
#endif

Expand Down
18 changes: 18 additions & 0 deletions avs_core/core/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,22 @@ class GlobalVarFrame
}
};

#ifdef XP_TLS
#include <avs/win.h>
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__
15 changes: 1 addition & 14 deletions avs_core/core/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,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}
Expand Down Expand Up @@ -288,19 +288,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;
}

Expand Down