stopThread annoyance

jules, i’m using the Thread class… and whatever i’ll do when i call stopThread(20000) even with high timeout value (20 seconds or so) i reach the brute force kill thread assert. the code of the run method is like this:

[code]void TimelineSystem::run()
{
while(!threadShouldExit())
{
int elapsedTime = Time::getMillisecondCounterHiRes();

	if(1) // hack
	{
		const MessageManagerLock mmlock;
		timelineActions->stepToNextFrame ();
		
		elapsedTime = Time::getMillisecondCounterHiRes() - elapsedTime;
	}

	if (elapsedTime<frameDurationInMilliseconds)
		wait(frameDurationInMilliseconds - elapsedTime);
}

}[/code]

maybe this is related to the usage of the MessageManagerLock ?

Well you’ve clearly got a deadlock. Very easy to debug these - you just break the program when it gets stuck, and look at where the threads are. Two of them will be sitting there waiting for each other’s locks.

You can use this software to detect location of deadlock in your source files provided you have a map file.

(Windows only)

thanx jules !
i’ve found it out… i was calling stopThread from inside the run function! what terrible things i was doing :wink:
what can i call from inside the thread to stop it ? is a good thing to just return from run or is better to call signalThreadToExit ?

If your thread wants to stop, it just returns - the signalling and stopThread() stuff is all just there to get the message to it that it should return asap.

ok now i got it… but i discovered that the deadlock is happening if i try to do something like DocumentWindow::setBounds in the thread, which in turn calls Win32ComponentPeer::setBounds which calls win32 function ::SetWindowPos which get stuck if called from the background thread… any workaround ?

It takes 2 critical sections for a deadlock, it can’t happen with only the message manager lock. Ah the joys of threading…

mmmh yeah, i’ve googled a bit and discovered that there are some function (win32) that can’t be called from within another thread than the main one, like SetFocus, SetWindowPos and some others. i’ve found some workaround but none seem to work… any clue ? if there isn’t a workaround i think i can stick back to the Timer usage, slow, expensive but working in any case… i thought using thread could be a better and faster solution, but actually it seems that it can’t be used widely

It’s really unwise to do any UI work on other threads - apart from problems like this, it’s just generally dangerous, and gives no performance advantage at all.

ok man ;D just trying out the possibility. now i’ve understood that is clearly unsafe… thanx.

I’ve just encountered the same kind of problem.
I created a thread to compute the peaks of a file so that I can display the waveform, and wanted to display the percentage accomplished in the waveform view.
My thread calls the component repaint() function and it kinda works but if I try to stop the thread from the UI thread, there’s a deadlock.

Any advice ?

Yeah, it’s much neater to make your thread object a ChangeBroadcaster, and the UI can register with it for callbacks when it’s got some new data. Then it’s up to the UI to repaint itself.

thanks Jules! I was just testing that and it works !
it’s really much nicer.

thanks again, very neat framework!