Skip to content

Commit 5d98c94

Browse files
committed
JRE-238 [736] java.awt.AWTError: access denied ("java.lang.RuntimePermission" "canInvokeInSystemThreadGroup")
Moved task execution on AppKit to the privileged block. Minor refactoring (cherry picked from commit 5dbb88471115c9e4a536ae37d0e6794de9e5ac9c)
1 parent 28774d6 commit 5d98c94

File tree

1 file changed

+53
-32
lines changed

1 file changed

+53
-32
lines changed

src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
package sun.java2d.opengl;
2727

2828
import java.awt.AWTException;
29+
import java.awt.AWTError;
2930
import java.awt.BufferCapabilities;
3031
import java.awt.Component;
3132
import java.awt.Graphics;
@@ -60,6 +61,9 @@
6061

6162
import sun.lwawt.LWComponentPeer;
6263
import sun.lwawt.macosx.CPlatformView;
64+
import sun.lwawt.macosx.CThreading;
65+
import java.security.PrivilegedAction;
66+
import java.util.concurrent.Callable;
6367

6468
public final class CGLGraphicsConfig extends CGraphicsConfig
6569
implements OGLGraphicsConfig
@@ -134,40 +138,57 @@ public static CGLGraphicsConfig getConfig(CGraphicsDevice device,
134138
return null;
135139
}
136140

137-
long cfginfo = 0;
138-
int textureSize = 0;
139-
final String ids[] = new String[1];
140-
OGLRenderQueue rq = OGLRenderQueue.getInstance();
141-
rq.lock();
142-
try {
143-
// getCGLConfigInfo() creates and destroys temporary
144-
// surfaces/contexts, so we should first invalidate the current
145-
// Java-level context and flush the queue...
146-
OGLContext.invalidateCurrentContext();
147-
148-
cfginfo = getCGLConfigInfo(device.getCGDisplayID(), pixfmt,
149-
kOpenGLSwapInterval);
150-
if (cfginfo != 0L) {
151-
textureSize = nativeGetMaxTextureSize();
152-
// 7160609: GL still fails to create a square texture of this
153-
// size. Half should be safe enough.
154-
// Explicitly not support a texture more than 2^14, see 8010999.
155-
textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
156-
OGLContext.setScratchSurface(cfginfo);
157-
rq.flushAndInvokeNow(() -> {
158-
ids[0] = OGLContext.getOGLIdString();
159-
});
141+
// Move CGLGraphicsConfig creation code to AppKit thread in order to avoid the
142+
// following deadlock:
143+
// 1) CGLGraphicsConfig.getCGLConfigInfo (called from EDT) takes RenderQueue.lock
144+
// 2) CGLLayer.drawInCGLContext is invoked on AppKit thread and
145+
// blocked on RenderQueue.lock
146+
// 1) invokes native block on AppKit and wait
147+
148+
Callable<CGLGraphicsConfig> command = () -> {
149+
long cfginfo;
150+
int textureSize = 0;
151+
final String ids[] = new String[1];
152+
OGLRenderQueue rq = OGLRenderQueue.getInstance();
153+
rq.lock();
154+
try {
155+
// getCGLConfigInfo() creates and destroys temporary
156+
// surfaces/contexts, so we should first invalidate the current
157+
// Java-level context and flush the queue...
158+
OGLContext.invalidateCurrentContext();
159+
160+
cfginfo = getCGLConfigInfo(device.getCGDisplayID(), pixfmt,
161+
kOpenGLSwapInterval);
162+
if (cfginfo != 0L) {
163+
textureSize = nativeGetMaxTextureSize();
164+
// 7160609: GL still fails to create a square texture of this
165+
// size. Half should be safe enough.
166+
// Explicitly not support a texture more than 2^14, see 8010999.
167+
textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
168+
OGLContext.setScratchSurface(cfginfo);
169+
rq.flushAndInvokeNow(() -> ids[0] = OGLContext.getOGLIdString());
170+
}
171+
} finally {
172+
rq.unlock();
173+
}
174+
if (cfginfo == 0) {
175+
return null;
160176
}
161-
} finally {
162-
rq.unlock();
163-
}
164-
if (cfginfo == 0) {
165-
return null;
166-
}
167177

168-
int oglCaps = getOGLCapabilities(cfginfo);
169-
ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
170-
return new CGLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps);
178+
int oglCaps = getOGLCapabilities(cfginfo);
179+
ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
180+
return new CGLGraphicsConfig(
181+
device, pixfmt, cfginfo, textureSize, caps);
182+
};
183+
184+
return java.security.AccessController.doPrivileged(
185+
(PrivilegedAction<CGLGraphicsConfig>) () -> {
186+
try {
187+
return CThreading.executeOnAppKit(command);
188+
} catch (Throwable throwable) {
189+
throw new AWTError(throwable.getMessage());
190+
}
191+
});
171192
}
172193

173194
static void refPConfigInfo(long pConfigInfo) {

0 commit comments

Comments
 (0)