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 @@ ...@@ -13,6 +13,40 @@
static DWORD currentTLS = TLS_OUT_OF_INDEXES; 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) extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{ {
switch (reason) switch (reason)
...@@ -29,36 +63,17 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved ...@@ -29,36 +63,17 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
// Fall throught to initialize index // Fall throught to initialize index
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
{ {
gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current)); gl::AllocateCurrent();
if (current)
{
TlsSetValue(currentTLS, current);
current->context = NULL;
current->display = NULL;
}
} }
break; break;
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
{ {
void *current = TlsGetValue(currentTLS); gl::DeallocateCurrent();
if (current)
{
LocalFree((HLOCAL)current);
}
} }
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
{ {
void *current = TlsGetValue(currentTLS); gl::DeallocateCurrent();
if (current)
{
LocalFree((HLOCAL)current);
}
TlsFree(currentTLS); TlsFree(currentTLS);
} }
break; break;
...@@ -71,10 +86,20 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved ...@@ -71,10 +86,20 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
namespace gl namespace gl
{ {
void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
Current *GetCurrentData()
{ {
Current *current = (Current*)TlsGetValue(currentTLS); 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->context = context;
current->display = display; current->display = display;
...@@ -86,7 +111,7 @@ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) ...@@ -86,7 +111,7 @@ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
Context *getContext() Context *getContext()
{ {
Current *current = (Current*)TlsGetValue(currentTLS); Current *current = GetCurrentData();
return current->context; return current->context;
} }
...@@ -112,7 +137,7 @@ Context *getNonLostContext() ...@@ -112,7 +137,7 @@ Context *getNonLostContext()
egl::Display *getDisplay() egl::Display *getDisplay()
{ {
Current *current = (Current*)TlsGetValue(currentTLS); Current *current = GetCurrentData();
return current->display; 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