将 SWT 与 JOGL 结合使用时随机崩溃(竞争条件?)

发布于 2024-11-25 01:24:33 字数 2450 浏览 1 评论 0 原文

我正在使用 JOGL 和 SWT/AWT 桥编写一个 SWT 应用程序,并且尝试在 Composite 内创建多个 GLCanvas 对象,然后我正在尝试放入选项卡内。当它工作时,它看起来像这样:

但大多数时候(大约75%,也许是随机的)它崩溃并显示以下错误消息:

Java 运行时环境检测到致命错误:
SIGSEGV (0xb) 位于 pc=0x0024843a,pid=8618,tid=2345560944

JRE 版本:6.0_22-b22
Java VM:OpenJDK Server VM(20.0-b11 混合模式 linux-x86 )
衍生品:IcedTea6 1.10.2
发行版:Ubuntu 11.04,软件包 6b22-1.10.2-0ubuntu1~11.04.1
有问题的框架:C
[libpthread.so.0+0x843a] __pthread_mutex_lock+0x11a

我也尝试过仅使用一个画布而不是两个画布,但仍然遇到相同的随机崩溃。有时,我会收到以下错误消息:

java: tpp.c:63: __pthread_tpp_change_priority: 断言 `new_prio == -1 || (new_prio >= __sched_fifo_min_prio && new_prio <= __sched_fifo_max_prio)' 失败。

大概存在线程问题,也许是竞争条件?奇怪的是,如果我尝试将复合材料直接放在外壳上而不是放在选项卡上,它工作正常(或者至少我没有看到它崩溃)。

相关的代码如下所示:

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);

VisualizerCanvas 构造函数如下所示:

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);
}

我是否使用 SWT 小部件/复合材料做了不应该做的事情?

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:

Working correctly

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=2345560944

JRE 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

想你的星星会说话 2024-12-02 01:24:33

最后自己解决了这个问题。事实证明,这确实是一个竞争条件 - 我正在 Linux 上的 Eclipse 中进行开发,我需要以下代码来防止 Linux 窗口事件丢失:

static {
    GLProfile.initSingleton(false);
}

我已经将其放入我的 VisualizerCanvas 中类,但不在我的 Visualizer 类中(第一段代码)。据推测,GLProfileVisualizerCanvas 正在争夺 JVM 加载的机会,GLProfile 有时会获胜,从而导致崩溃。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文