Random crashes when using SWT with JOGL (race condition?)
I'm writing an SWT app using JOGL and the SWT/AWT bridge, and I'm trying to create multiple GLCanvas
objects inside a Composite
, which I'm then trying to put inside a tab. When it works, it looks like this:
But most of the time (about 75% perhaps, at random) it crashes with the following error message:
A fatal error has been detected by the Java Runtime Environment:
SIGSEGV (0xb) at pc=0x0024843a, pid=8618, tid=2345560944JRE version: 6.0_22-b22
Java VM: OpenJDK Server VM (20.0-b11 mixed mode linux-x86 ) Derivative: IcedTea6 1.10.2 Distribution: Ubuntu 11.04, package 6b22-1.10.2-0ubuntu1~11.04.1 Problematic frame: C [libpthread.so.0+0x843a] __pthread_mutex_lock+0x11a
I've also tried it with just one canvas instead of two, and I still get the same random crash. Occasionally, I get this error message instead:
java: tpp.c:63: __pthread_tpp_change_priority: Assertion `new_prio == -1 || (new_prio >= __sched_fifo_min_prio && new_prio <= __sched_fifo_max_prio)' failed.
Presumably there's a threading problem, maybe a race condition? Strangely enough, if I try to put the composite straight onto the shell instead of onto a tab, it works fine (or at least I haven't seen it crash).
The relevant bit of code looks like this:
tabFolder = new CTabFolder(shell, SWT.BORDER);
tabFolder.setSimple(false);
final Composite composite = new Composite(tabFolder, SWT.NONE);
composite.setLayout(new FillLayout());
new VisualizerCanvas(composite, MeshFactory.loadObj("meshes/teapot_sealed.obj"));
new VisualizerCanvas(composite, MeshFactory.loadObj("meshes/duck.obj"));
final CTabItem item = new CTabItem(tabFolder, SWT.CLOSE);
item.setText("Test");
item.setImage(new Image(display, "img/test.jpg"));
item.setControl(composite);
The VisualizerCanvas
constructor looks like this:
public VisualizerCanvas(Composite parent, Mesh mesh)
{
// Set up the canvas
GLProfile glProfile = GLProfile.getDefault();
GLCapabilities glCapabilities = new GLCapabilities(glProfile);
glCapabilities.setDoubleBuffered(true);
glCapabilities.setHardwareAccelerated(true);
glCanvas = new GLCanvas(glCapabilities);
glCanvas.addGLEventListener(this);
// Create the embedded AWT frame using the SWT/AWT bridge
Composite composite = new开发者_开发知识库 Composite(parent, SWT.EMBEDDED | SWT.BORDER | SWT.NO_BACKGROUND);
composite.setLayout(new FillLayout());
Frame frame = SWT_AWT.new_Frame(composite);
frame.add(glCanvas);
// Add an animator to automatically update the canvas at 30fps
animator = new FPSAnimator(glCanvas, 30);
animator.add(glCanvas);
animator.start();
this.mesh = MeshFactory.normalizeMesh(mesh);
}
Am I doing something I shouldn't with SWT widgets/composites?
Finally solved the problem myself. Turns out it was indeed a race condition - I'm developing in Eclipse on Linux, and I need the following piece of code to prevent Linux window events getting lost:
static {
GLProfile.initSingleton(false);
}
I'd already put this in my VisualizerCanvas
class, but not in my Visualizer
class (the first piece of code). Presumably GLProfile
and VisualizerCanvas
were in a race to be loaded by the JVM, and GLProfile
would sometimes win, resulting in a crash.
精彩评论