MessageManagerLock inexplicably causing abort() function to be called

So I’ve been experimenting with threads in JUCE, I’m just using the native C++ threads because I’m more familiar with them. (Is it better practice to use JUCE threads?)

Anyway, I’ve got a simple method that creates a thread like this:

void DrawGraphics::engageClock()

	mPlayState = PlayState::Playing;
	unsigned int rate = 2;

	DBG("main thread : " << std::hash<std::thread::id>{}(std::this_thread::get_id()));

	std::thread clockWork(&DrawGraphics::clock, this, rate);


Which just starts an audio clock on another thread as seen below…

void DrawGraphics::clock(unsigned int rate) // accepts an integer as Hz

	const MessageManagerLock mml(Thread::getCurrentThread());

	if (mml.lockWasGained())
		DBG("mml lock succesful");
		DBG("mml locked unsuccesful");

        ... DO CLOCK STUFF


It seems to work fine but then in the console this gets printed and the program crashes:

main thread : 15735606657672724526
Debug Error!

Program: ...afix-0_2\Builds\VisualStudio2017\x64\Debug\App\grafix-0_2.exe

abort() has been called

(Press Retry to debug the application)
mml gained
DSP thread : 15675618735505290966

So two different threads are clearly created but abort() is being called once the MessageManagerLock was gained.

Does anyone know why this could be? Should I just be using JUCE threads?


You create the std::thread as a local variable that gets immediately destroyed and you didn’t detach the thread. If you detach it, using the thread as a local variable can work. (It’s not a recommended pattern, though.)

The abort() happens because you destroy the non-detached thread before joining into it. (And joining wouldn’t probably make much sense in the context of that code because it would just block the current thread.)

1 Like

Oh wow yeah that was exactly the problem.

Thanks so much @Xenakios

EDIT for posterity: I kept the thread as a local variable then detached and everything was gravy