Lockup on start with StandardGame and GameTaskQueueManager

Every now and then my game locks up on start when I'm using GameTaskQueueManager. So I put together a smallish test…

It freezes with this output:

creating simpleGameState

calling GameTaskQueueManager

waiting for future.get()



Am I doing anything wrong here? :?


import com.jme.input.MouseInput;
import com.jmex.editors.swing.settings.GameSettingsPanel;
import com.jmex.game.StandardGame;

public class TestStartLockup {

    private static StandardGame game;
    private static SomeGameState someGameState;

    public static void main(String[] args) throws Exception {
        game = new StandardGame("Game");
        if (!GameSettingsPanel.prompt(game.getSettings()))
            System.exit(0);
        game.start();
        MouseInput.get().setCursorVisible(true);
        System.out.println("creating simpleGameState");
        someGameState = new SomeGameState();
        System.out.println("created simpleGameState");
    }
}


import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import com.jme.util.GameTaskQueueManager;
import com.jmex.game.state.GameState;

public class SomeGameState extends GameState {
    public SomeGameState() throws Exception {
        System.out.println("calling GameTaskQueueManager");
        Future<Object> future = GameTaskQueueManager.getManager().update(new Callable<Object>() {
            public Object call() throws Exception {
                System.out.println("inside call()");
                return null;
            }
        });
        System.out.println("waiting for future.get()");
        future.get();
        System.out.println("returned from future.get()");
    }

    public void cleanup() {
    }
    public void render(float arg0) {
    }
    public void update(float arg0) {
    }
}

i have the same problem, except its not happening every now and then … but like one in ten times when i start my game.

Are you running from CVS?  I'll try to test this and see if I can reproduce it.  I use StandardGame all the time and have yet to have my game lock up.

Yes, from a few days old CVS. I'll update to latest and try again, and also check if the lockups are dependent on setCursorVisible or not.



Edit: I've updated to latest CVS and it still happens. I've had it lock up once without calling setCursorVisible but that took a lot more tries so I think setCursorVisible makes a difference. While calling setCursorVisible I've even had the test lock up on me 3 times in a row…

i am running V0.11



maybe its just a coincidence that i have the same symptoms.



regards,

Andi

Did you try sending the MouseInput.get().setCursorVisible(true);  call to the GameTaskQueueManager ?



Maybe it needs to be executed in the OpenGl Thread.

He is…that actually seems to be what is causing the lock though.

Ok, I've found out what causes my problems. It seems the constructor for the "Singleton" :stuck_out_tongue: GameTaskQueueManager is actually run twice in some rare cases, which causes the problems I'm seeing. :smiley:



Perhaps a lock or something could be added after "if (MANAGER_INSTANCE == null)" to make it double-check before calling the constructor? That shouldn't affect performance in any way? I'd love to fix up a smallish patch but I'm tiered and I really have to get to bed now. I'll make a suggested fix tomorrow though, unless someone else beats me to it. :slight_smile:

I fixed it and checked it in.  I'm really surprised I made such a stupid mistake.



Let this be a lesson to those learning about thread-safety.  ALWAYS make the static method that gets/creates your singleton synchronized. :wink:



Very good work on the find Gathers!  Everyone update and verify this resolves all the problems…if not we'll have to have Gathers look deeper.  :stuck_out_tongue:

If it makes you feel any better, you didn't write that class.  :wink:

hehe…well, uh…  :roll:



I knew I wrote a lot of  system…I just assumed you just took my buggy code and cleaned it up a bit. :o

damn, didnt solve my problem … but nice find!  :wink:



Andy

It did solve my problems, thanks for the quick fix! :slight_smile:



But from a pure performance point of view, why not use something like this? Isn't there a very slight performance impact from making the whole getManager() synchronized?


    public static GameTaskQueueManager getManager() {
        if (MANAGER_INSTANCE == null)
            synchronized (GameTaskQueueManager.class) {
                if (MANAGER_INSTANCE == null)
                    MANAGER_INSTANCE = new GameTaskQueueManager();
            }
        return MANAGER_INSTANCE;
    }

not a good idea, the cause is complex, though - see double checked locking (anti-)pattern

Oh, I see, thanks. :slight_smile:

For those interested there is a good explanation at http://en.wikipedia.org/wiki/Double-checked_locking

darkfrog said:

He is...that actually seems to be what is causing the lock though.


but but in the first post MouseInput.get().setCursorVisible(true); is called outside the OpenGl thread no?

You're right on both points.  I just saw GameTaskQueueManager in the subject and assumed it was being used for the cursor status.  Yes, it should be in the OpenGL thread to reliably work.



Is anyone else still experience lock-ups in-game related to GameTaskQueue?