Commit bbb43c17 by Jamie Madill

Fix initialization of thread local storage in libGLESv2.

When an app would load libGLESv2.dll via LoadModule, then would call methods on a thread that was already created, we could creash because of uninitialized thread local storage. BUG=angle:488 Change-Id: I9b05de462232a16d639c58ec07386b7c38a01793 Reviewed-on: https://chromium-review.googlesource.com/179197Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 6d397646
......@@ -13,6 +13,40 @@
static DWORD currentTLS = TLS_OUT_OF_INDEXES;
namespace gl
{
Current *AllocateCurrent()
{
Current *current = (Current*)LocalAlloc(LPTR, sizeof(Current));
if (!current)
{
ERR("Could not allocate thread local storage.");
return NULL;
}
ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
TlsSetValue(currentTLS, current);
current->context = NULL;
current->display = NULL;
return current;
}
void DeallocateCurrent()
{
void *current = TlsGetValue(currentTLS);
if (current)
{
LocalFree((HLOCAL)current);
}
}
}
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
......@@ -29,36 +63,17 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
// Fall throught to initialize index
case DLL_THREAD_ATTACH:
{
gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
if (current)
{
TlsSetValue(currentTLS, current);
current->context = NULL;
current->display = NULL;
}
gl::AllocateCurrent();
}
break;
case DLL_THREAD_DETACH:
{
void *current = TlsGetValue(currentTLS);
if (current)
{
LocalFree((HLOCAL)current);
}
gl::DeallocateCurrent();
}
break;
case DLL_PROCESS_DETACH:
{
void *current = TlsGetValue(currentTLS);
if (current)
{
LocalFree((HLOCAL)current);
}
gl::DeallocateCurrent();
TlsFree(currentTLS);
}
break;
......@@ -71,10 +86,20 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
namespace gl
{
void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
Current *GetCurrentData()
{
Current *current = (Current*)TlsGetValue(currentTLS);
// ANGLE issue 488: when the dll is loaded after thread initialization,
// thread local storage (current) might not exist yet.
return (current ? current : AllocateCurrent());
}
void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
{
Current *current = GetCurrentData();
current->context = context;
current->display = display;
......@@ -86,7 +111,7 @@ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
Context *getContext()
{
Current *current = (Current*)TlsGetValue(currentTLS);
Current *current = GetCurrentData();
return current->context;
}
......@@ -112,7 +137,7 @@ Context *getNonLostContext()
egl::Display *getDisplay()
{
Current *current = (Current*)TlsGetValue(currentTLS);
Current *current = GetCurrentData();
return current->display;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment