Keyboard.create() Blocks When Called From Other Thread

Started by jonkri, February 14, 2010, 12:09:41

Previous topic - Next topic

jonkri

I have found that the Keyboard class blocks when Keyboard.create() and Keyboard.next() are called. I'm assuming this will be the behaviour of any method which tries to lock OpenGLPackageAccess.global_lock but I have not verifid this. These lock-ups didn't show up on neither Windows Vista or in a Red Hat system over at my friend's school. Below is a test case which reproduces the error on my machine.

I'm getting the lock-ups on Ubuntu 9.10 on a Lenovo ThinkPad T61 with a 32bit Core2 Duo processor. Vista (which does not cause this behaviour) runs on the very same hardware. I will ask my friend to fill in the details of the Red Hat system.

I have tried both Sun's JDK 1.6.0_15 and OpenJDK 1.6.0 both of which caused the behavior. They were both provided by the standard Ubuntu repositories.

Note: I could not copy the code because of crappy restrictions in Word, so you may have to change something in order for it to actually compile.

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;

public class KeyboardCreateBugTestCase
{
	private static final boolean IS_CREATING_KEYBOARD_FROM_DISPLAY_THREAD = false;

	private static boolean isRunning = true;

	private static Runnable keyboardCreator = new Runnable()
	{
		public void run()
		{
			try
			{
				System.out.print(Thread.currentThread().getName() + ": Creating Keyboard...");
				Keyboard.create();
				System.out.println("Done!");
			}
			catch(LWJGLException exception)
			{
				exception.printStackTrace();
			}
		}
	}

	public static void main(String args[])
	{
		try
		{
			Display.setDisplayMode(Display.getDesktopDisplayMode());

			Display.create();
		}
		catch(LWJGLException exception)
		{
			exception.printStackTrace();
		}

		Display.setTitle("KeyboardCreateBugTestCase");

		if(IS_CREATING_KEYBOARD_FROM_DISPLAY_THREAD)
		{
			try
			{
				System.out.print(Thread.currentThread().getName() + ": Creating Keyboard...");
				Keyboard.create();
				System.out.println("Done!");
			}
			catch(LWJGLException exception)
			{
				exception.printStackTrace();
			}
		}
		else
		{
			new Thread(keyboardCreator, "OtherThread").start();
		}

		while(isRunning)
		{
			Display.update();

			if(Display.isCloseRequested())
			{
				isRunning = false;
			}
		}
	}
}


Setting IS_CREATING_KEYBOARD_FROM_DISPLAY_THREAD to true gives me the following (expected) output:

main: Creating keyboard... Done!

Setting IS_CREATING_KEYBOARD_FROM_DISPLAY_THREAD to false gives me the following (not expected) output:

OtherThread: Creating keyboard...

One interesting thing in the second case is that when I close the window it will unlock and print the "Done!".

Please let me know if there is anything I can do to assist with to help find this bug.

Warm regards,
Jon Kristensen

betel

Quote from: jonkri on February 14, 2010, 12:09:41
I will ask my friend to fill in the details of the Red Hat system.

On this system KeyboardCreateBugTestCase works as expected, with "Done!" printed without delay in both cases.

It's an Inte Core2 Duo running 32-bit Red Hat Enterprise Linux Server release 5.3 with a 2.6.18 kernel and Sun's JRE 1.6.0_17.
I used the same jinput and lwjgl (2.1.0).

betel

I solved this on my 64-bit Ubuntu 9.10 machine with Sun's JDK 1.6.0_15 by putting a
Thread.yield();
in the loop. I.m guessing this will fix it on jonkri's machine too, and that the Red Hat system just did time slicing, or something, differently in some way.

Fool Running

I think (someone correct me if I'm wrong) that the Keyboard can only be created on the thread that created the display (or the thread that owns the OpenGL context, not sure). Also, I would assume that you would want to wait to start your main update loop until the keyboard is created. It's possible that the Display.update() is blocking while Keyboard.create() is happening since Display.update() calls Keyboard.poll().
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D