Is the following line a race condition between the OpenGL thread and the JUCE MessageThread?
In the file
juce/examples/GUI/OpenGLDemo.h, line 848 (in develop branch), in the function
glViewport (0, 0, roundToInt (desktopScale * (float) getWidth()), roundToInt (desktopScale * (float) getHeight()));
This line accesses
getHeight() while running on the OpenGL thread via the
I set a breakpoint here and went back in the stack trace to
OpenGLContext.cpp -> renderFrame() and I saw that the
mmLock local variable had its member
lockWasSuccessful set to false, meaning that the OpenGL thread is not holding a Message Thread lock when accessing
Component data. The
Component data could simultaneously be modified by the MessageThread, causing a race condition.
The screenshots below show what I saw in the debugger.
In the past, it was my understanding that the OpenGL thread always holds a
MessageManager::Lock in the
renderOpenGL() callback. But, this is not always true. The OpenGL thread only holds a
MessageManager::Lock when the associated
OpenGLContext is attached to render
juce::Components, not purely GL code, and any of those
Components are marked to be redrawn by the GL thread. If no
Components need to be redrawn, and there is other rendering being done by the GL thread in a
renderOpenGL() callback, then the GL thread will not be holding a
I learned this from this post: OpenGL Thread MessageManager Lock - #4 by fr810
Lastly, I see, also in
OpenGLDemo.h line 679 (develop branch), a
MessageManagerLock is requested before running a bit of code on the GL thread:
const MessageManagerLock mml (ThreadPoolJob::getCurrentThreadPoolJob()); if (! mml.lockWasGained()) return false; g.drawFittedText (String (Time::getCurrentTime().getMilliseconds()), image.getBounds(), Justification::centred, 1);
I am not sure why this particular code is guarded by the lock while many
Graphics calls above, for an
Image, are not guarded. (I am not entirely sure which JUCE methods/objects are unsafe to access on a thread other than the Message Thread.)
If I were to access juce Message Thread data in a
renderOpenGL() callback, should I request a MessageManagerLock in the same fashion?
const MessageManagerLock mml (ThreadPoolJob::getCurrentThreadPoolJob()); if (! mml.lockWasGained()) return false;
Thanks for any help and clarity on this topic!