Missing Locks In Linux OpenGL?


#1

We have some plugins that use juce::OpenGLContext for rendering graphs and we’ve been running into a deadlocking issue on Linux when multiple instances are open… Essentially we’re experiencing what this user describes:

Our plugins run into the same issue where deadlocking occurs when glXMakeCurrent() or other glX methods get called concurrently.

In juce_OpenGL_linux_X11.h I see some functions acquire a ScopedXLock, but not all do. The deadlocking resolved once we added locks to makeActive(), deactivateCurrentContext(), etc. Is there a reason not all the methods making glX calls don’t currently acquire a lock?

Thanks!


#2

I can’t see a good reason why those methods don’t require a lock. If you could provide your changes I’ll take a proper look.


#3

Hey Tom, here’s a diff with the additions. So far we haven’t experienced any deadlocking after updating this file

diff --git a/modules/juce_opengl/native/juce_OpenGL_linux_X11.h b/modules/juce_opengl/native/juce_OpenGL_linux_X11.h
index 9de02cb28..b5afcad91 100644
--- a/modules/juce_opengl/native/juce_OpenGL_linux_X11.h
+++ b/modules/juce_opengl/native/juce_OpenGL_linux_X11.h
@@ -153,7 +153,8 @@ public:
     }
 
     void shutdownOnRenderThread()
-    {
+    {
+        ScopedXLock xlock (display);
         context = nullptr;
         deactivateCurrentContext();
         glXDestroyContext (display, renderContext);
@@ -161,24 +162,28 @@ public:
     }
 
     bool makeActive() const noexcept
-    {
+    {
+        ScopedXLock xlock (display);
         return renderContext != 0
                  && glXMakeCurrent (display, embeddedWindow, renderContext);
     }
 
     bool isActive() const noexcept
-    {
+    {
+        ScopedXLock xlock (display);
         return glXGetCurrentContext() == renderContext && renderContext != 0;
     }
 
     static void deactivateCurrentContext()
     {
-        ScopedXDisplay xDisplay;
+        ScopedXDisplay xDisplay;
+        ScopedXLock xlock (xDisplay.display);
         glXMakeCurrent (xDisplay.display, None, 0);
     }
 
     void swapBuffers()
-    {
+    {
+        ScopedXLock xlock (display);
         glXSwapBuffers (display, embeddedWindow);
     }
 
@@ -201,7 +206,8 @@ public:
 
         if (auto GLXSwapIntervalSGI
               = (PFNGLXSWAPINTERVALSGIPROC) OpenGLHelpers::getExtensionFunction ("glXSwapIntervalSGI"))
-        {
+        {
+            ScopedXLock xlock (display);
             swapFrames = numFramesPerSwap;
             GLXSwapIntervalSGI (numFramesPerSwap);
             return true;

#4