Thread doesn't exit cleanly, why?


#1

I currently doing a little app that lists contents of a given directory.
Looks like this.

It basically works, but only when I let it run until it’s finished.
When I press the “Cancel” button in the dialog box I get a “”!! killing thread by force !!" triggered breakpoint.

This is the code I use for listing the directory contents in a text editor (roughly based on code I gathered from going through the API docs):
(DirIterator class inherits from ThreadWithProgressWindow)

void DirIterator::run()
{
	DirectoryIterator di(m_filePath, m_searchRecursively, "*", File::findFilesAndDirectories);

	    while (di.next()) {	
		const MessageManagerLock mmLock;
		double progress = (double)di.getEstimatedProgress();
		setProgress(progress);

		m_textEditor->insertTextAtCaret(di.getFile().getFullPathName() + newLine);

		if (threadShouldExit()) {
			break;
		}
        }	
}

I invoke the thread from a GUI component:

void GUIComponent::buttonClicked (Button* buttonThatWasClicked)
{
   // ...
    else if (buttonThatWasClicked == m_goBtn)
    {
		m_DirIterator = new DirIterator(this);
		if (m_DirIterator->runThread()) {

		}
		else {
			m_DirIterator->stopThread(1000);
		}
    }

Setting a breakpoint at DirIterator::threadShouldExit() I notice it doesn’t seem to get called when clicking the “Exit” button, which I think may be the cause of the problem.

But why, what’s wrong here ?

(I should say that besides being new to JUCE I’m also new to thread management).

Thanks.


#2

https://www.juce.com/doc/classMessageManagerLock#a294fab36d4e9fe48cc2b52b36974111c

Note the bit about likely deadlocks if you don’t bother giving it a thread to check.


#3

Yay, it works replacing

while (di.next()) {	
	const MessageManagerLock mmLock;
        //...

with

while (di.next()) {	
	const MessageManagerLock mmLock (Thread::getCurrentThread());
        if (!mmLock.lockWasGained())
	   return;
        //...

Thanks.

However I still don’t fully understand what’s the flaw with my original code (after reading the linked API doc), so I’d be happy if someone could elaborate.
Where / why exactly (supposedly) does a deadlock happen there ?