0

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?

Haydn V. Harach
  • 1,265
  • 1
  • 18
  • 36
  • 2
    Presumably you want `PrimaryThread thread(&config, &window);` – T.C. Jun 11 '15 at 00:47
  • Oh god, I feel like an idiot now... That was exactly what was wrong, and it fixed everything. Could you make an answer reply so I can mark it answered and give you rep? – Haydn V. Harach Jun 11 '15 at 00:52
  • You never created an actual thread. See the link I gave above. – Tim Biegeleisen Jun 11 '15 at 00:57
  • It actually did successfully create the thread, and it did run using the class' member function. That wasn't the issue. The issue was that I wasn't actually creating a `PrimaryThread` object, I was just calling it's constructor on an "object" that, I don't know, only existed for the duration of the constructor? I don't know why it didn't give me a compiler error. – Haydn V. Harach Jun 11 '15 at 01:03
  • 1
    @TimBiegeleisen You are confusing Windows' `CreateThread` and C++11 `std::thread`. – T.C. Jun 11 '15 at 01:04
  • I guess it's obvious when a Java developer starts trolling around C++ questions looking for points ^ ^. – Tim Biegeleisen Jun 11 '15 at 01:42

1 Answers1

1

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

T.C.
  • 133,968
  • 17
  • 288
  • 421