1.4.1_02 fullscreen deadlock

in j2se 1.4.1_02, a deadlock occurs about half the time on my machine. full screen mode will be set, and the display mode will change, but java will hang, and you’ll be left with a blank screen and a mouse cursor.

turns out there’s a potential java deadlock between the main thread and AWT-eventqueue thread when calling window.createBufferStrategy()

it occurs about half the time on my machine (windows xp, geforece4, latest video drivers) and didn’t occur in 1.4.1_01

i submitted a bug, but thought i’d post a workaround here. just synchronize with the window’s tree lock for the entire fullscreen/displaymode/bufferstrategy process:


synchronized (frame.[b]getTreeLock()[/b]) { 
  device.setFullScreenWindow(frame);
  if (displayMode != null &&
    device.isDisplayChangeSupported())
  {
    try {
      device.setDisplayMode(displayMode);
    }
    catch (IllegalArgumentException ex) { }
  }
  frame.createBufferStrategy(2);
}

the page for this bug is here:
http://developer.java.sun.com/developer/bugParade/bugs/4826573.html

ouch, this bug was commited to tiger, which is still a year or so off. i guess that means it can’t be fixed with the current api/spec without breaking something else.

ironically, the deadlock fix i posted here actually creates a deadlock on Mac OS X’s java 1.4.1_01. good times.

so, here’s another workaround that’s cross platform (at least on the mac and windows machines i tested) and makes a little more sense based on what the problem is.
call createBufferStrategy in the awt event dispatch thread:


device.setFullScreenWindow(frame); 
if (displayMode != null && device.isDisplayChangeSupported()) { 
  try { 
    device.setDisplayMode(displayMode); 
  } 
  catch (IllegalArgumentException ex) { } 
}
EventQueue.invokeAndWait(new Runnable() {
  public void run() {
    frame.createBufferStrategy(2);
  }
});

this will make sure createBufferStrategy can’t deadlock with the event dispatch thread, since it’s now run in the same thread.