blob: af3a020b8a4d40197ec22d9dbcf3149397da4df2 [file] [log] [blame]
From a91304c3193b63fa71e840ebfa7e055c6845f673 Mon Sep 17 00:00:00 2001
From: Iosif Antochi <iosif.antochi@imgtec.com>
Date: Wed, 14 Jun 2017 14:49:55 +0100
Subject: [PATCH 10/11] egl: automatically call eglReleaseThread on thread
termination
EGL thread cleanup conformance tests could run out of memory as the contexts
were not freed even though the application requested to have them deleted.
This was caused by the fact that the contexts were still current on their
threads when delete was called and (in order not to block any potential
pending renders) they were just marked for delete.
Fix this by calling eglReleaseThread on thread termination. This is safe to
do even if this was already called by the application since, according to the
EGL 1.5 spec, eglReleaseThread can be called multiple times without error.
Fixes:
dEQP-EGL.functional.thread_cleanup.multi_context_*
dEQP-EGL.functional.robustness.create_context.query_robust_access
---
src/egl/main/eglcurrent.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index 479f231fb8f..d20ec64e654 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -137,13 +137,37 @@ _eglDestroyThreadInfo(_EGLThreadInfo *t)
}
+/**
+ * Delete/free a _EGLThreadInfo object.
+ */
+static void
+_eglDestroyThreadInfoCallback(_EGLThreadInfo *t)
+{
+ /* If this callback is called on thread termination then try to also give a
+ * chance to cleanup to the client drivers. If called for module termination
+ * then just release the thread information as calling eglReleaseThread
+ * would result in a deadlock.
+ */
+ if (_egl_TSDInitialized) {
+ /* The callback handler has replaced the TLS entry, which is passed in as
+ * 't', with NULL. Restore it here so that the release thread finds it in
+ * the TLS entry.
+ */
+ _eglSetTSD(t);
+ eglReleaseThread();
+ } else {
+ _eglDestroyThreadInfo(t);
+ }
+}
+
+
/**
* Make sure TSD is initialized and return current value.
*/
static inline _EGLThreadInfo *
_eglCheckedGetTSD(void)
{
- if (_eglInitTSD(&_eglDestroyThreadInfo) != EGL_TRUE) {
+ if (_eglInitTSD(&_eglDestroyThreadInfoCallback) != EGL_TRUE) {
_eglLog(_EGL_FATAL, "failed to initialize \"current\" system");
return NULL;
}
--
2.22.0