GLFW on another thread

I’ve built a GLFW wrapper and I’d like to run it on another thread to my game logic. I wish to have all GL and GLFW calls on this new thread and none on this one (I’m not splitting rendering, only delegating it).

The issue arises when I execute the program and I get the following error:


Program: ...\CLionProjects\Engine-C\cmake-build-debug\Test.exe
File: ...\CLionProjects\Engine-C\deps\glfw-3.3.6\src\window.c, Line 479

Expression: window != NULL

When debugging, the window appears very briefly but closes by itself and a printout tells me that the main render loop does in fact run.

My code summarises to:

# include <thread>
//omitted std

class Wrapper{
void operator()(){
    //glfw script from https://www.glfw.org/documentation.html
    //basic glfw window, opengl context, loop, etc...
}
}

int main(){
    //running Wrapper on another thread does not work
    Wrapper* rendering_engine = new Wrapper();
    thread render_thread(*rendering_engine);

    //game logic, exit on user presses X

    render_thread.join()
    delete render_thread;
    return 0;

    //running Wrapper on this process works fine
    //Wrapper* rendering_engine = new Wrapper();
    //(*rendering_engine)();
    //return 0;
}

Can anyone please help me understand what the problem with this threading is?

Many thanks :slight_smile:

Looks like window.c line 479 comes from glfwWindowShouldClose() function: https://github.com/glfw/glfw/blob/3.3.6/src/window.c#L479

Are you calling glfwWindowShouldClose function in main thread with window argument that gets set only in Wrapper operator()? Maybe your Wrapper thread has not yet set window variable that you use in main thread, so it is still initialized to NULL?

Also it is not safe to use GLFWwindow* across threads. Depending on OS it may not work. It is better if you communicate whatever Wrapper thread needs to communicate to main thread with your own code without using glfw functions. Read carefully Thread safety section in docs: GLFW: Introduction to the API

Nope, currently, my game logic is empty so there should be no reason for the window to close other than the user pressing X.
Could it be possible that the main thread reaches the end of scope and deletes engine (which in turns calls glfwWindowShouldClose)? I specifically wrote thread.join() so that the main thread would wait for the renderer.

I don’t know - that’s your code, put breakpoints and check call-stack in debugger to see where it gets first and who/why calls glfwWindowShouldClose function.

Debugged a bit more, found another problem - upon closing the window another error came up - C0000005 - access violation. I realised also that the wrapper’s destructor was called before the glfw loop had started, strangely. And on some runs, the destructor would be called twice.
I added an id member to the wrapper which is set by copying a static member and incrementing it.
Turns out that the wrapper is created and instantly deleted.
I believe this has something to do with the way I run the render engine, namely the move semantics of the wrapper and the thread object.
I can’t see another wrapper being constructed, so it must be moved/copied. This also explains the access violation.
(I think)

I’d suggest not doing any new’s or move semantics, just put your code in function or use lambda:

thread render_thread([]() {
   ... thread code, or call function that should run in thread
});
... rest of main code