summaryrefslogtreecommitdiff
path: root/src/dispatch_wgl.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2013-12-17 09:31:39 -0800
committerEric Anholt <eric@anholt.net>2013-12-17 12:11:05 -0800
commit9a7be0784faba0d97a32051a873d7feb47981a37 (patch)
treeab1e3ff4bb950aee5dd0c1844c0389b06236bd71 /src/dispatch_wgl.c
parent8022cda75d65f537c48d4b43b44879abe558c1b7 (diff)
downloadlibepoxy-9a7be0784faba0d97a32051a873d7feb47981a37.tar.gz
win32: Use thread local storage to get us a dispatch table per thread.
Diffstat (limited to 'src/dispatch_wgl.c')
-rw-r--r--src/dispatch_wgl.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/dispatch_wgl.c b/src/dispatch_wgl.c
index fe871d9..0161ad4 100644
--- a/src/dispatch_wgl.c
+++ b/src/dispatch_wgl.c
@@ -58,3 +58,62 @@ epoxy_has_wgl_extension(HDC hdc, const char *ext)
return epoxy_extension_in_string(getext(hdc), ext);
}
+
+static void
+reset_dispatch_table(void)
+{
+ gl_init_dispatch_table();
+ wgl_init_dispatch_table();
+}
+
+/**
+ * This global symbol is apparently looked up by Windows when loading
+ * a DLL, but it doesn't declare the prototype.
+ */
+BOOL WINAPI
+DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved);
+
+BOOL WINAPI
+DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
+{
+ void *data;
+
+ switch (reason) {
+ case DLL_PROCESS_ATTACH:
+ gl_tls_index = TlsAlloc();
+ if (gl_tls_index == TLS_OUT_OF_INDEXES)
+ return FALSE;
+ wgl_tls_index = TlsAlloc();
+ if (wgl_tls_index == TLS_OUT_OF_INDEXES)
+ return FALSE;
+
+ /* FALLTHROUGH */
+
+ case DLL_THREAD_ATTACH:
+ data = LocalAlloc(LPTR, gl_tls_size);
+ TlsSetValue(gl_tls_index, data);
+
+ data = LocalAlloc(LPTR, wgl_tls_size);
+ TlsSetValue(wgl_tls_index, data);
+
+ reset_dispatch_table();
+ break;
+
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ data = TlsGetValue(gl_tls_index);
+ LocalFree(data);
+
+ data = TlsGetValue(wgl_tls_index);
+ LocalFree(data);
+ break;
+
+ if (reason == DLL_PROCESS_DETACH) {
+ TlsFree(gl_tls_index);
+ TlsFree(wgl_tls_index);
+ }
+ break;
+ }
+
+ return TRUE;
+}