Login  Register

Re: [2.0 RC3] PBuffer uses awtlock during display

Posted by Tovi on Sep 29, 2011; 9:14am
URL: https://forum.jogamp.org/2-0-RC3-PBuffer-uses-awtlock-during-display-tp3355580p3378752.html

Sven, I copied TestGearsAWT and modified it to demonstrate the issue with PBuffer deadlocks when AWT is used.

I also don't see the point of locking AWT for PBuffers, which are used for offscreen rendering. I believe this test should succeed without a call to GLProfile.initSingleton(true). (though right now it doesn't, and it will timeout after 10 seconds). The test is very artificial, but it proves a point: You perform a task on a non-awt thread, while also keeping an awt lock. This should not lock the application.

Regards,
Tovi




import com.jogamp.opengl.test.junit.util.UITestCase;
import org.junit.*;
import sun.awt.SunToolkit;

import javax.media.opengl.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestPBufferDeadLock extends UITestCase {
  static GLProfile glp;
  static int width, height;
  private ExecutorService fSingleThreadExecutorService;

  @BeforeClass
  public static void initClass() {
    glp = GLProfile.getDefault();
    Assert.assertNotNull( glp );
    width = 512;
    height = 512;
  }

  @AfterClass
  public static void releaseClass() {
  }

  @Override @Before
  public void setUp() {
    super.setUp();
    fSingleThreadExecutorService = Executors.newFixedThreadPool( 1 );
  }

  protected void runTestGL( GLCapabilities caps ) throws InterruptedException {
    final GLPbuffer pbuffer = GLDrawableFactory.getFactory( GLProfile.get( "GL2" ) ).createGLPbuffer(
        null,
        caps,
        new DefaultGLCapabilitiesChooser(),
        512,
        512,
        null
    );

    final boolean[] done = {false};
    Runnable runnable = new Runnable() {
      public void run() {
        pbuffer.display();
        done[ 0 ] = true;
      }
    };
    try {
      SunToolkit.awtLock();
      fSingleThreadExecutorService.execute( runnable );
      while ( !done[ 0 ] ) {
        try {
          Thread.sleep( 100 );
        }
        catch ( InterruptedException e ) {
          Assert.fail( "Failed to sleep" );
        }
      }

    }
    finally {
      SunToolkit.awtUnlock();
    }
  }

  @Test(timeout = 10000) //10 second timeout
  public void testDeadlock() throws InterruptedException {
    GLCapabilities caps = new GLCapabilities( glp );
    runTestGL( caps );
  }

  static long duration = 500; // ms

  public static void main( String args[] ) {
    for ( int i = 0; i < args.length; i++ ) {
      if ( args[ i ].equals( "-time" ) ) {
        i++;
        try {
          duration = Integer.parseInt( args[ i ] );
        }
        catch ( Exception ex ) {
          ex.printStackTrace();
        }
      }
    }
    org.junit.runner.JUnitCore.main( TestPBufferDeadLock.class.getName() );
  }
}