Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Can't get LWJGL 0.98 to Webstart on OS X  (Read 3169 times)
0 Members and 1 Guest are viewing this topic.
Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Posted 2005-08-19 19:21:59 »

Everything works fine until I jar everything up for webstart.

With webstart, the app opens a window (nothing drawn), then promptly falls over with a huge dump.   Windows works fine.  The Mac dumps.  I re-fetched the osx-native and re-jared it, but still the same.  Only lwjgl.jar, lwjgl_utils.jar & lwjgl-osx.jar are involved.

The odd thing is when I compile and run on the Mac with Netbeans using liblwjgl.jnilib directly all is fine. I cleared out all my webstart caches, but no change.

 If anyone has got 0.98 working via Webstart, could they let me know.  Conversely, if your Mac webstart dumps, that'd also be useful input.

The dump's huge.
Rather than post the lot, here is the problem thread:

Quote
Thread 15 Crashed:
0   com.apple.Foundation        0x9289de80 _NSRaiseError + 264
1   libawt.jnilib               0x9deb0a70 LookupClass + 120
2   libawt.jnilib               0x9deb08fc LookupMemberID + 128
3   libawt.jnilib               0x9deb94d4 GetLongField + 104
4   libjawt.dylib               0x9e1b1978 awt_DrawingSurface_GetDrawingSurfaceInfo + 92
5   liblwjgl.jnilib             0x09f69df0 Java_org_lwjgl_opengl_AWTSurfaceLock_lockAndInitHandle + 220
6   <<00000000>>    0x04556264 0 + 72704612
7   <<00000000>>    0x0454f930 0 + 72677680
8   <<00000000>>    0x0454f9c0 0 + 72677824
9   <<00000000>>    0x0454fab0 0 + 72678064
10  <<00000000>>    0x0454fab0 0 + 72678064
11  <<00000000>>    0x0454f9c0 0 + 72677824
12  <<00000000>>    0x0454fe10 0 + 72678928
13  <<00000000>>    0x0454fab0 0 + 72678064
14  <<00000000>>    0x0454fab0 0 + 72678064
15  <<00000000>>    0x0454fab0 0 + 72678064
16  <<00000000>>    0x0454fab0 0 + 72678064
17  <<00000000>>    0x0454fab0 0 + 72678064
18  <<00000000>>    0x046816fc 0 + 73930492
19  <<00000000>>    0x0468fe40 0 + 73989696
20  <<00000000>>    0x0454fab0 0 + 72678064
21  <<00000000>>    0x0454d160 0 + 72667488
22  libclient.dylib             0x9cdc1d88 operator new[](unsigned long) + 365560
23  libclient.dylib             0x9cdc1bd4 operator new[](unsigned long) + 365124
24  libclient.dylib             0x9cddb49c JVM_NewInstanceFromConstructor + 3880
25  libclient.dylib             0x9ce5f01c JVM_InvokeMethod + 1396
26  libclient.dylib             0x9ce5eca4 JVM_InvokeMethod + 508
27  <<00000000>>    0x04556264 0 + 72704612
28  <<00000000>>    0x0454f9c0 0 + 72677824
29  <<00000000>>    0x0454f9c0 0 + 72677824
30  <<00000000>>    0x0454fd20 0 + 72678688
31  <<00000000>>    0x0454f9c0 0 + 72677824
32  <<00000000>>    0x0454fab0 0 + 72678064
33  <<00000000>>    0x0454fab0 0 + 72678064
34  <<00000000>>    0x0454fab0 0 + 72678064
35  <<00000000>>    0x0454f9c0 0 + 72677824
36  <<00000000>>    0x0454f9c0 0 + 72677824
37  <<00000000>>    0x0454fe10 0 + 72678928
38  <<00000000>>    0x0454d160 0 + 72667488
39  libclient.dylib             0x9cdc1d88 operator new[](unsigned long) + 365560
40  libclient.dylib             0x9cdc1bd4 operator new[](unsigned long) + 365124
41  libclient.dylib             0x9cdce348 JVM_StartThread + 2432
42  libclient.dylib             0x9cdce23c JVM_StartThread + 2164
43  libclient.dylib             0x9cdce174 JVM_StartThread + 1964
44  libclient.dylib             0x9cdce040 JVM_StartThread + 1656
45  libclient.dylib             0x9cd5f4e4 operator new(unsigned long) + 7716
46  libSystem.B.dylib           0x9002c3d4 _pthread_body + 96

To experience this yourself try the latest version of SharpShooter16k (on the Mac)
http://www.circuitswamp.org/projects/sharpshooter16k.html

Hopefully, someone has an idea on this, I'm stumped.

Alan  Smiley

Time flies like a bird. Fruit flies like a banana.
Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #1 - Posted 2005-08-19 21:35:22 »

Update:

If I go back to using org.lwjgl.util.Display rather than org.lwjgl.opengl.Display and sign the application so that the utility library will work, then the problem goes away.  Thus it probably isn't a LWJGL 0.98 issue, but something more generic.  I guess when Cas fixes that library, I can go back to using it  -> problem solved (hopefully).

In the meantime, the investigation continues Smiley

I think its a signing problem.  Something I'm doing with Display unique to the Mac requires full privileges.  That would explain why the code ran under Netbeans, but failed on Webstart (both on the Mac).

...

It appears to be the act of creating the window that is failing.  It does not appear possible to create a display (fullscreen or windowed) unless the app is signed on the Mac. 

Time flies like a bird. Fruit flies like a banana.
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #2 - Posted 2005-08-20 00:47:15 »

This may be an instance of Sun JDK bug 4796548 which I believe is still present on Mac OS X. There is a workaround for this in the JOGL workspace which you can find by searching in all files for that bug ID.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #3 - Posted 2005-08-20 09:02:40 »

Thanks for the suggestion.  It does look suspiciously similar
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4796548

Since giving all permissions works round it, I would imagine putting a doPrivileged() around the offending call would work round it (my panacea for all problems).

This isn't an applet, but the issue looks very similar.

Quote
The problem comes from a RuntimePermission issue with applets.  Specifically,
the new code (as of build 7) checks whether the class passed into
GetDrawingSurface() is not only of type java.awt.Component (which was a check
performed in the earlier code), but also of some internal sun.* classes.
The call to FindClass() apparently throws an exception for sun.* classes
when the RuntimePermission policy is not set appropriately.  Once this
exception is thrown, all further JNI calls fail (including the later
check to FindClass() for java.awt.Component).  GetDrawingSurface() ends
up returning NULL, which is then dereferenced in the test app and the
applet thus crashes with the reported ExceptionAccess error.

Time flies like a bird. Fruit flies like a banana.
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #4 - Posted 2005-08-20 09:26:55 »

Since giving all permissions works round it, I would imagine putting a doPrivileged() around the offending call would work round it (my panacea for all problems).
Yup, found the code needed to fix this:
https://jogl.dev.java.net/source/browse/jogl/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java?r1=1.6&r2=1.7

We will implement this shortly - but it wont be available before 0.99.

Thanks for the heads up Ken!

Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #5 - Posted 2005-08-20 10:09:48 »

Thanks to all Smiley

Alan Smiley

Time flies like a bird. Fruit flies like a banana.
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #6 - Posted 2005-08-20 10:33:57 »

upon further inspection - I am not sure this is the cause...
the call to GetDrawingSurfaceInfo is made from native code, so we should always have the privileges
besides, it was fixed in 2003?

Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #7 - Posted 2005-08-20 10:55:12 »

I was looking at this bit, but haven't traced back through all the calls yet.  However the sun bug report suggets that once the fault has occurred, all further native calls fail, so this could be a symptom rather than the cause.


org.lwjgl.opengl.MacOSXCanvasPeerInfo
1  
2  
3  
4  
5  
6  
7  
private final AWTSurfaceLock awt_surface = new AWTSurfaceLock();

protected void initHandle(Canvas canvas) throws LWJGLException {
  nInitHandle(awt_surface.lockAndGetHandle(canvas), getHandle());
}

private static native void nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle) throws LWJGLException;


org.lwjgl.opengl.AWTSurfaceLock
1  
  private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas canvas) throws LWJGLException;

Time flies like a bird. Fruit flies like a banana.
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #8 - Posted 2005-08-20 11:05:16 »

for the fun of it - can you make a doPrivileged around the lockAndInitHandle method?

Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #9 - Posted 2005-08-20 11:21:05 »

I'll see if I can compile it & subsitute it in the jar.

Meanwhile, I traced it back

org.lwjgl.opengl.Display

public static void create(...) {
  ...
  peer_info = display_impl.createPeerInfo(pixel_format);
  context = new Context(peer_info, shared_drawable != null ? shared_drawable.getContext() : null);
  ...
  createWindow();
  initContext();
  ...
}

private static void createWindow() ... {
  int window_x;
  int window_y;
  ...
  display_impl.createWindow(current_mode, fullscreen, window_x, window_y);
  makeCurrent();
      
  setTitle(title);
  initControls();
  setVSyncEnabled(vsync);
  ...
}


public static void makeCurrent() throws LWJGLException {
...
  context.makeCurrent();
}


org.lwjgl.opengl.Context

public synchronized void makeCurrent() throws LWJGLException {
  checkAccess();
  ...
  current_context_local.set(this);
  implementation.makeCurrent(peer_info, handle);
  GLContext.useContext(this);
}

org.lwjgl.opengl.ContextImplementation

  public void makeCurrent(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException;


org.lwjgl.opengl.MacOSXContextImplementation

public void makeCurrent(PeerInfo peer_info, ByteBuffer handle) throws LWJGLException {
  ByteBuffer peer_handle = peer_info.lockAndGetHandle();
...
}

org.lwjgl.opengl.PeerInfo

private final void lockAndInitHandle() throws LWJGLException {
  doLockAndInitHandle();
}

public synchronized final ByteBuffer lockAndGetHandle() throws LWJGLException {
...
  doLockAndInitHandle();
...
}

protected abstract void doLockAndInitHandle() throws LWJGLException;


org.lwjgl.opengl.MacOSXDisplayPeerInfo

protected void doLockAndInitHandle() throws LWJGLException {
...
  MacOSXFrame frame = ((MacOSXDisplay)Display.getImplementation()).getFrame();
...
  Canvas gl_canvas = frame.getCanvas();
  initHandle(gl_canvas);
...
}


org.lwjgl.opengl.MacOSXCanvasPeerInfo

private final AWTSurfaceLock awt_surface = new AWTSurfaceLock();

protected void initHandle(Canvas canvas) throws LWJGLException {
  nInitHandle(awt_surface.lockAndGetHandle(canvas), getHandle());
}

private static native void nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle) throws LWJGLException;


org.lwjgl.opengl.AWTSurfaceLock

  private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas canvas) throws LWJGLException;

Time flies like a bird. Fruit flies like a banana.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

« JGO Spiffy Duke »


Medals: 434
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #10 - Posted 2005-08-20 12:17:53 »

By the way I fixed org.lwjgl.util.Display in CVS.

Cas Smiley

Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #11 - Posted 2005-08-20 12:27:22 »

Success!!!  Grin

... and you've fixed the util library as well Smiley

Alan

(Time to go & enjoy the rest of the day outside)

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
package org.lwjgl.opengl;

import java.awt.Canvas;
import java.nio.ByteBuffer;
import java.security.*; // ADW *****************************

import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;

/**
 * $Id: AWTSurfaceLock.java,v 1.4 2005/05/04 20:59:34 cix_foo Exp $
 *
 * @author elias_naur <elias_naur@users.sourceforge.net>
 * @version $Revision: 1.4 $
 */

final class AWTSurfaceLock {
   private final static int WAIT_DELAY_MILLIS = 100;
   
   private final ByteBuffer lock_buffer;

   public AWTSurfaceLock() {
      lock_buffer = createHandle();
   }
   private static native ByteBuffer createHandle();

   public ByteBuffer lockAndGetHandle(Canvas canvas) throws LWJGLException {
      while (!privilegedLockAndInitHandle(lock_buffer, canvas)) {
         LWJGLUtil.log("Could not get drawing surface info, retrying...");
         try {
            Thread.sleep(WAIT_DELAY_MILLIS);
         } catch (InterruptedException e) {
            LWJGLUtil.log("Interrupted while retrying: " + e);
         }
      }
               
      return lock_buffer;
   }
       
        private boolean privilegedLockAndInitHandle(ByteBuffer lock_buffer, Canvas canvas) throws LWJGLException {
           final ByteBuffer lock_buffer2 = lock_buffer;
           final Canvas canvas2 = canvas;
            try {
                final Object result = AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public Object run() throws org.lwjgl.LWJGLException {
                           if (lockAndInitHandle(
                               lock_buffer2, canvas2))
                               return Boolean.TRUE;
                           else
                               return Boolean.FALSE;
                        }
                    });
                return ((Boolean)result).booleanValue();   
            } catch (PrivilegedActionException e) {
                throw (org.lwjgl.LWJGLException) e.getException();
            }
        }

   private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas canvas) throws LWJGLException;

   protected void unlock() throws LWJGLException {
      nUnlock(lock_buffer);
   }
   private static native void nUnlock(ByteBuffer lock_buffer) throws LWJGLException;
}


Edit: This could be tidied a bit
- LWJGLException rather than org.lwjgl.LWJGLException
- Boolean.valueOf(lockAndInitHandle(...)) rather than the if statement

Time flies like a bird. Fruit flies like a banana.
Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #12 - Posted 2005-08-20 13:03:31 »

Full Tidied version

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
/*
 * Copyright (c) 2002-2004 LWJGL Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'LWJGL' nor the names of
 *   its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.lwjgl.opengl;

import java.awt.Canvas;
import java.nio.ByteBuffer;

import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;

import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;

/**
 * $Id: AWTSurfaceLock.java,v 1.4 2005/05/04 20:59:34 cix_foo Exp $
 *
 * @author elias_naur <elias_naur@users.sourceforge.net>
 * @version $Revision: 1.4 $
 */

final class AWTSurfaceLock {
   private final static int WAIT_DELAY_MILLIS = 100;
   
   private final ByteBuffer lock_buffer;

   public AWTSurfaceLock() {
      lock_buffer = createHandle();
   }
   private static native ByteBuffer createHandle();

   public ByteBuffer lockAndGetHandle(Canvas canvas) throws LWJGLException {
      while (!privilegedLockAndInitHandle(lock_buffer, canvas)) {
         LWJGLUtil.log("Could not get drawing surface info, retrying...");
         try {
            Thread.sleep(WAIT_DELAY_MILLIS);
         } catch (InterruptedException e) {
            LWJGLUtil.log("Interrupted while retrying: " + e);
         }
      }
               
      return lock_buffer;
   }
       
   private boolean privilegedLockAndInitHandle(ByteBuffer lock_buffer, Canvas canvas) throws LWJGLException {
      final ByteBuffer lock_buffer2 = lock_buffer;
      final Canvas canvas2 = canvas;
      try {
         final Object result = AccessController.doPrivileged(
            new PrivilegedExceptionAction() {
               public Object run() throws LWJGLException {
                  return Boolean.valueOf(lockAndInitHandle(
                     lock_buffer2, canvas2));
               }
            });
         return ((Boolean)result).booleanValue();   
      } catch (PrivilegedActionException e) {
         throw (LWJGLException) e.getException();
      }
   }

   private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas canvas) throws LWJGLException;

   protected void unlock() throws LWJGLException {
      nUnlock(lock_buffer);
   }
   private static native void nUnlock(ByteBuffer lock_buffer) throws LWJGLException;
}

Time flies like a bird. Fruit flies like a banana.
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #13 - Posted 2005-08-20 13:48:15 »

excellent!
but uhm... why the while loop ? - it fails for some times ?

Offline Ken Russell

JGO Coder




Java games rock!


« Reply #14 - Posted 2005-08-20 16:37:25 »

upon further inspection - I am not sure this is the cause...
the call to GetDrawingSurfaceInfo is made from native code, so we should always have the privileges

The problem is that your native code is calling native code in the JDK which calls JNI_FindClass internally. The JDK native code had a bug where it was not requesting elevated privileges before making its own FindClass calls, so upon walking the stack for the security check it was encountering user code which did not have the privileges to see these internal classes. Security rights are granted based on the contents of the Java stack, not the native stack (which the JVM doesn't have any knowledge of).

Quote
besides, it was fixed in 2003?

Apparently not in Apple's port of the JDK.

From looking at the above fix it seems that it is not optimal. To work around this bug in the JDK it is only necessary to request elevated privileges during the first call to GetDrawingSurfaceInfo from native code. AccessController.doPrivileged() is expensive so you don't want to do it every frame.
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #15 - Posted 2005-08-20 16:59:29 »

Try this one Alan_W
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
/*
 * Copyright (c) 2002-2004 LWJGL Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'LWJGL' nor the names of
 *   its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.lwjgl.opengl;

import java.awt.Canvas;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;

import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;

/**
 * $Id: AWTSurfaceLock.java,v 1.4 2005/05/04 20:59:34 cix_foo Exp $
 *
 * @author elias_naur <elias_naur@users.sourceforge.net>
 * @version $Revision: 1.4 $
 */

final class AWTSurfaceLock {
   private final static int WAIT_DELAY_MILLIS = 100;
   
   private final ByteBuffer lock_buffer;
   
   private boolean needPrivileged = true;

   public AWTSurfaceLock() {
      lock_buffer = createHandle();
   }
   private static native ByteBuffer createHandle();

   public ByteBuffer lockAndGetHandle(final Canvas canvas) throws LWJGLException {
      boolean lockAquired = false;
      while (!lockAquired) {
         // We need to elevate priveleges because of an AWT bug. Please see
         // http://192.18.37.44/forums/index.php?topic=10572 for a discussion.
         // It is only needed on first call, so we avoid it on all subsequent calls
         // due to performance.
         if(needPrivileged) {
            Boolean result = (Boolean) AccessController.doPrivileged(new PrivilegedAction() {
               public Object run() {
                  try {
                     return lockAndInitHandle(lock_buffer, canvas);
                  } catch (LWJGLException le) {
                     return false;
                  }
               };
            });
           
            // no longer need elevated priveleges
            if(result.booleanValue()) {
               needPrivileged = false;
            }
         } else {
            lockAquired = lockAndInitHandle(lock_buffer, canvas);
         }
         LWJGLUtil.log("Could not get drawing surface info, retrying...");
         try {
            Thread.sleep(WAIT_DELAY_MILLIS);
         } catch (InterruptedException e) {
            LWJGLUtil.log("Interrupted while retrying: " + e);
         }
      }
      return lock_buffer;
   }
   private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas canvas) throws LWJGLException;

   protected void unlock() throws LWJGLException {
      nUnlock(lock_buffer);
   }
   private static native void nUnlock(ByteBuffer lock_buffer) throws LWJGLException;
}

Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #16 - Posted 2005-08-20 17:33:43 »

@Matzon

Your's is tidier with the 'final' keyword, but there's a couple more improvements: Smiley
- On the first time around set 'lock_acquired', otherwise the code always retries at least once.
- Catch and throw exceptions from native code.  Currently any exceptions inside the native code are swallowed, potentially causing an  endless loop.

Alan

How about:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
package org.lwjgl.opengl;

import java.awt.Canvas;
import java.nio.ByteBuffer;

import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;

import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;

/**
 * $Id: AWTSurfaceLock.java,v 1.4 2005/05/04 20:59:34 cix_foo Exp $
 *
 * @author elias_naur <elias_naur@users.sourceforge.net>
 * @version $Revision: 1.4 $
 */

final class AWTSurfaceLock {
   private final static int WAIT_DELAY_MILLIS = 100;
   
   private final ByteBuffer lock_buffer;
   private boolean firstLockSucceeded = false;

   public AWTSurfaceLock() {
      lock_buffer = createHandle();
   }
   private static native ByteBuffer createHandle();

   public ByteBuffer lockAndGetHandle(Canvas canvas) throws LWJGLException {
      while (!privilegedLockAndInitHandle(canvas)) {
         LWJGLUtil.log("Could not get drawing surface info, retrying...");
         try {
            Thread.sleep(WAIT_DELAY_MILLIS);
         } catch (InterruptedException e) {
            LWJGLUtil.log("Interrupted while retrying: " + e);
         }
      }
               
      return lock_buffer;
   }
       
   private boolean privilegedLockAndInitHandle(final Canvas canvas) throws LWJGLException {
      // Workaround for Sun JDK bug 4796548 which still exists in java for OS X
      if (firstLockSucceeded)
         return lockAndInitHandle(lock_buffer, canvas);
      else
         try {
            final Object result = AccessController.doPrivileged(
               new PrivilegedExceptionAction() {
                  public Object run() throws LWJGLException {
                     return Boolean.valueOf(lockAndInitHandle(
                        lock_buffer, canvas));
                  }
               });
            firstLockSucceeded = ((Boolean)result).booleanValue();
            return firstLockSucceeded;
         } catch (PrivilegedActionException e) {
            throw (LWJGLException) e.getException();
         }
   }

   private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas canvas) throws LWJGLException;

   protected void unlock() throws LWJGLException {
      nUnlock(lock_buffer);
   }
   private static native void nUnlock(ByteBuffer lock_buffer) throws LWJGLException;
}


I have tested this.

(The 'other' unrelated problem on the Mac is that switching from full-screen to windowed and back causes a crash after a couple of cycles.  Always going to fullscreen it appears.  It's a problem with Java2D as well, so I'm not hopeful of finding a fix for that one.  This bug report looks interesting http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4922401 - Nope - not even a long sleep after changing modes does any good and other workarounds suggested for Java2D already appear to be in the LWJGL code - I think the only option is to refuse to change fullscreen<=>windowed more than once i.e. if we start in fullscreen, then allow a change to windowed, but refuse to go fullscreen again, at least on the mac)

Time flies like a bird. Fruit flies like a banana.
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #17 - Posted 2005-08-20 19:08:44 »

fixed, thanks to you both!

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (32 views)
2014-12-15 09:26:44

Mr.CodeIt (23 views)
2014-12-14 19:50:38

BurntPizza (51 views)
2014-12-09 22:41:13

BurntPizza (84 views)
2014-12-08 04:46:31

JscottyBieshaar (45 views)
2014-12-05 12:39:02

SHC (59 views)
2014-12-03 16:27:13

CopyableCougar4 (58 views)
2014-11-29 21:32:03

toopeicgaming1999 (123 views)
2014-11-26 15:22:04

toopeicgaming1999 (114 views)
2014-11-26 15:20:36

toopeicgaming1999 (32 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!