Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,13 @@ public void run() {
}

LOGGER.log(Level.FINE, "Using LWJGL {0}", Version.getVersion());

// HACK: If you use waitFor(), unlock it beforehand to initialize the
// context on the fly.
synchronized (createdLock) {
created.set(true);
createdLock.notifyAll();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Setting the created flag to true at the start of the run() method is premature and breaks the contract of the JmeContext lifecycle. In jMonkeyEngine, isCreated() is generally expected to mean that the context is fully initialized, including the renderer and input systems. By signaling completion here, any thread calling waitFor(true) will resume while the context is still in a "waiting for visibility" state, and getRenderer() will return null. This can lead to NullPointerException in application code that assumes readiness after waitFor(true) returns.

A more robust fix for the deadlock would be to handle the EDT check in the create(boolean waitFor) method rather than prematurely signaling that the context is created. Additionally, ensure that signaling the waiting thread (such as the EDT) is handled in a finally block to ensure the waiting thread is unblocked even if an exception occurs during initialization.

References
  1. In AWT-native integrations, signaling mechanisms between the rendering thread and the EDT should be placed in finally blocks to ensure the EDT is unblocked even if cleanup or initialization fails.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the context is created on the fly, waitFor() is not practical with LWJGLX... so it's best to disable it.


while (true) {
if (needResize.getAndSet(false)) {
Expand Down Expand Up @@ -552,7 +559,7 @@ public void run() {
// All this does is call swapBuffers().
// If the canvas is not active, there's no need to waste time
// doing that.
if (renderable.get() && canvas.hasContext()) {
if (renderable.get() && canvas.hasContext() && canvas.isValid()) {
try {
if (allowSwapBuffers && autoFlush) {
// calls swap buffers | lock, etc.
Expand Down Expand Up @@ -715,6 +722,7 @@ protected void createContext(AppSettings settings) {

canvas.createContext();
canvas.makeCurrent();
canvas.validate();
Comment thread
JNightRider marked this conversation as resolved.
Outdated

// This will activate the "effective data" scrubber.
if (settings.getBoolean("GLDataEffectiveDebug")) {
Expand Down