0017-egl-automatically-call-eglReleaseThread-on-thread-te.patch 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. From df5f4dae5d92afb8d9922197efabd32c26e665a7 Mon Sep 17 00:00:00 2001
  2. From: Iosif Antochi <iosif.antochi@imgtec.com>
  3. Date: Wed, 14 Jun 2017 14:49:55 +0100
  4. Subject: [PATCH] egl: automatically call eglReleaseThread on thread
  5. termination
  6. EGL thread cleanup conformance tests could run out of memory as the contexts
  7. were not freed even though the application requested to have them deleted.
  8. This was caused by the fact that the contexts were still current on their
  9. threads when delete was called and (in order not to block any potential
  10. pending renders) they were just marked for delete.
  11. Fix this by calling eglReleaseThread on thread termination. This is safe to
  12. do even if this was already called by the application since, according to the
  13. EGL 1.5 spec, eglReleaseThread can be called multiple times without error.
  14. Fixes:
  15. dEQP-EGL.functional.thread_cleanup.multi_context_*
  16. dEQP-EGL.functional.robustness.create_context.query_robust_access
  17. ---
  18. src/egl/main/eglcurrent.c | 27 ++++++++++++++++++++++++++-
  19. 1 file changed, 26 insertions(+), 1 deletion(-)
  20. diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
  21. index 11277d3..c87eac0 100644
  22. --- a/src/egl/main/eglcurrent.c
  23. +++ b/src/egl/main/eglcurrent.c
  24. @@ -44,6 +44,7 @@ static mtx_t _egl_TSDMutex = _MTX_INITIALIZER_NP;
  25. static EGLBoolean _egl_TSDInitialized;
  26. static tss_t _egl_TSD;
  27. static void _eglDestroyThreadInfo(_EGLThreadInfo *t);
  28. +static void _eglDestroyThreadInfoCallback(_EGLThreadInfo *t);
  29. #ifdef USE_ELF_TLS
  30. static __THREAD_INITIAL_EXEC const _EGLThreadInfo *_egl_TLS;
  31. @@ -86,7 +87,7 @@ static inline EGLBoolean _eglInitTSD()
  32. /* check again after acquiring lock */
  33. if (!_egl_TSDInitialized) {
  34. - if (tss_create(&_egl_TSD, (void (*)(void *)) _eglDestroyThreadInfo) != thrd_success) {
  35. + if (tss_create(&_egl_TSD, (void (*)(void *)) _eglDestroyThreadInfoCallback) != thrd_success) {
  36. mtx_unlock(&_egl_TSDMutex);
  37. return EGL_FALSE;
  38. }
  39. @@ -135,6 +136,30 @@ _eglDestroyThreadInfo(_EGLThreadInfo *t)
  40. }
  41. +/**
  42. + * Delete/free a _EGLThreadInfo object.
  43. + */
  44. +static void
  45. +_eglDestroyThreadInfoCallback(_EGLThreadInfo *t)
  46. +{
  47. + /* If this callback is called on thread termination then try to also give a
  48. + * chance to cleanup to the client drivers. If called for module termination
  49. + * then just release the thread information as calling eglReleaseThread
  50. + * would result in a deadlock.
  51. + */
  52. + if (_egl_TSDInitialized) {
  53. + /* The callback handler has replaced the TLS entry, which is passed in as
  54. + * 't', with NULL. Restore it here so that the release thread finds it in
  55. + * the TLS entry.
  56. + */
  57. + _eglSetTSD(t);
  58. + eglReleaseThread();
  59. + } else {
  60. + _eglDestroyThreadInfo(t);
  61. + }
  62. +}
  63. +
  64. +
  65. /**
  66. * Make sure TSD is initialized and return current value.
  67. */