Mutithreaded LWJGL - Works... Sometimes

I’m trying to implement two OpenGL contexts on different threads, all is well so-far but after glfwInit is called I get a dump file. It works flawlessly sometimes, and other times it gives me this file (summarized)

Java Threads: ( => current thread )
  0x00007fc9c823f800 JavaThread "Timer-0" [_thread_blocked, id=2248, stack(0x00007fc99693c000,0x00007fc996a3d000)]
  0x00007fc9c823d800 JavaThread "pool-1-thread-2" [_thread_in_native, id=2247, stack(0x00007fc996a3d000,0x00007fc996b3e000)]
=>0x00007fc9c823c000 JavaThread "pool-1-thread-1" [_thread_in_native, id=2246, stack(0x00007fc996b3e000,0x00007fc996c3f000)]
  0x00007fc9c81d4000 JavaThread "Monitor Ctrl-Break" daemon [_thread_in_native, id=2243, stack(0x00007fc99715f000,0x00007fc997260000)]
  0x00007fc9c80d5000 JavaThread "Service Thread" daemon [_thread_blocked, id=2241, stack(0x00007fc99756a000,0x00007fc99766b000)]
  0x00007fc9c80bf800 JavaThread "C1 CompilerThread3" daemon [_thread_blocked, id=2240, stack(0x00007fc99766b000,0x00007fc99776c000)]
  0x00007fc9c80bb000 JavaThread "C2 CompilerThread2" daemon [_thread_blocked, id=2239, stack(0x00007fc99776c000,0x00007fc99786d000)]
  0x00007fc9c80b9800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=2238, stack(0x00007fc99786d000,0x00007fc99796e000)]
  0x00007fc9c80b6800 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=2237, stack(0x00007fc99796e000,0x00007fc997a6f000)]
  0x00007fc9c80b4800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=2236, stack(0x00007fc997a6f000,0x00007fc997b70000)]
  0x00007fc9c808c800 JavaThread "Finalizer" daemon [_thread_blocked, id=2228, stack(0x00007fc997cfd000,0x00007fc997dfe000)]
  0x00007fc9c8088000 JavaThread "Reference Handler" daemon [_thread_blocked, id=2226, stack(0x00007fc997dfe000,0x00007fc997eff000)]
  0x00007fc9c800b000 JavaThread "main" [_thread_in_Java, id=2205, stack(0x00007fc9d224e000,0x00007fc9d234f000)]

The one it’s pointing to is a thread created by the ExecutorService. Here’s the java frames:

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.lwjgl.glfw.GLFW.nglfwInit()I+0
j  org.lwjgl.glfw.GLFW.glfwInit()I+12
j  ecumene.astro.view.common.gl.GLView.run()V+21
j  ecumene.astro.view.ASViewStepWorker.run()V+4
j  java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V+95
j  java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub

It’s glfwInit that’s causing these errors, and I hardly know why it does. (My best guess is that I’m not destroying objects correctly, or not allocating enough memory… either way native code usually breaks because of memory stuff :stuck_out_tongue: )

Here’s the run method, which is pretty unimpressive (I really just threw it together with some stuff I found online, it worked for a little while, then the glfwInit started crashing the VM)

@Override
public void run() {
    super.run();
    glfwPollEvents();

    glfwSetErrorCallback(errorCallback = new GLFWErrorCallback() {
        @Override
        public void invoke(int error, long description) {
            System.err.println("glerror occurred: " + error);
        }
    });
    if (glfwInit() != GL_TRUE) {
        System.err.println("Error initializing GLFW");
    }

    windowID = glfwCreateWindow(640, 480, "My GLFW Window", NULL, NULL);

    if (windowID == NULL) {
        System.err.println("Error creating a window");
    }

    glfwDefaultWindowHints();
    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    glfwMakeContextCurrent(windowID);

    GLContext.createFromCurrent();
    glfwSwapInterval(1);

    float now, last, delta;

    last = 0;

    init();

    while (glfwWindowShouldClose(windowID) != GL_TRUE) {
        now = (float) glfwGetTime();
        delta = now - last;
        last = now;

        update(delta);
        render(delta);

        glfwPollEvents();
        glfwSwapBuffers(windowID);
    }

    dispose();
}

I’m still very new to concurrent programming (hence the use of executorservice) but any pointers to how I may have broken this are very helpful!