Thread object destroys itself immediately after creation?

205 views Asked by At

I created a class, PrimaryThread, to handle most of my application's work outside of the main thread, where it wont be interfered with by code that needs to work on the main thread and might be blocking. I create the PrimaryThread object inside main() on the stack, and then... it immediately destroys itself.

Here's my main() function:

int main(int, char**)
{
    Main::running = true;
    cout << "Hello World!\n";

    Config config("config.ini");
    Window window(&config);
    PrimaryThread(&config, &window);
    cout << "  blah\n";

    while(Main::isRunning())
    {
        window.handleMessages();
    }

    cout << "Goodbye World!\n";
    return 0;
}

Here's the constructor and destructor of the PrimaryThread class:

PrimaryThread(Config* config, Window* window)
:   _primaryThread(main, this),
    _config(config),
    _window(window)
{
    if (!_primaryThread.joinable())
    {
        std::cerr << "!Failed to initialize primary thread!\n";
        Main::shutDown();
    }
}

~PrimaryThread()
{
    std::cout << "Destructing PrimaryThread class.\n";
    Main::shutDown();
    _primaryThread.join();
}

PrimaryThread::_primaryThread is a private variable, an std::thread (not a pointer, so allocated on the stack). PrimaryThread::main() is a private method, whose address is passed to the constructor of _primaryThread. It does properly construct and run the thread.

The loop inside PrimaryThread::main relies on Main::isRunning(), which returns false after any thread calls Main::shutDown(). If I comment out that line, the thread loops properly, but the main thread is trapped in a freeze that never ends because _primaryThread.join() blocks it, and with no way to receive input (input is handled in window.handleMessages(), on the main thread), the primary thread never breaks from the loop.

Without commenting any lines, my console ends up looking like:

Hello World!
Window opened. // Window::Window(), on main thread
Destructing PrimaryThread class.
Primary thread started // PrimaryThread::main(), on primary thread
primary thread shutting down // as above
  blah
Goodbye World!
Window closed. // Window::~Window(), on main thread

If I comment out _primaryThread.join() in the destructor, I get a crash. I have no idea why, the debugger I'm using can't trace it, and my console shows:

terminate called without an active exception

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

...and then the process returns 3.

What the heck is going on here?

1

There are 1 answers

0
T.C. On BEST ANSWER

PrimaryThread(&config, &window); creates an unnamed temporary PrimaryThread object that's destroyed at the ;.